﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SpiceNet.Models.BSIM3;
using SpiceNet.Circuits;
using SpiceNet.Diagnostics;
using SpiceNet.Parameters;

namespace SpiceNet.Models
{
    /// <summary>
    /// A BSIM 3.3.0 Mosfet model
    /// </summary>
    public class BSIM3v3Model : Model
    {
        /// <summary>
        /// Enumeration of MOSFET types
        /// </summary>
        public enum MosfetType { NMOS, PMOS };

        /// <summary>
        /// Internally calculated variables
        /// </summary>
        public Dictionary<Tuple<double, double>, SizeDependParam> Params = new Dictionary<Tuple<double, double>, SizeDependParam>();

        #region Parameters
        /* Optional parameters */
        public Parameter<int> BSIM3mobMod { get; private set; }
        public Parameter<int> BSIM3binUnit { get; private set; }
        public Parameter<int> BSIM3capMod { get; private set; }
        public Parameter<int> BSIM3paramChk { get; private set; }
        public Parameter<int> BSIM3noiMod { get; private set; }
        public Parameter<int> BSIM3acnqsMod { get; private set; }
        public Parameter<double> BSIM3type { get; private set; }
        public Parameter<double> BSIM3tox { get; private set; }
        public Parameter<string> BSIM3version { get; private set; }
        public Parameter<double> BSIM3toxm { get; private set; }
        public Parameter<double> BSIM3cdsc { get; private set; }
        public Parameter<double> BSIM3cdscb { get; private set; }
        public Parameter<double> BSIM3cdscd { get; private set; }
        public Parameter<double> BSIM3cit { get; private set; }
        public Parameter<double> BSIM3nfactor { get; private set; }
        public Parameter<double> BSIM3xj { get; private set; }
        public Parameter<double> BSIM3vsat { get; private set; }
        public Parameter<double> BSIM3at { get; private set; }
        public Parameter<double> BSIM3a0 { get; private set; }
        public Parameter<double> BSIM3ags { get; private set; }
        public Parameter<double> BSIM3a1 { get; private set; }
        public Parameter<double> BSIM3a2 { get; private set; }
        public Parameter<double> BSIM3keta { get; private set; }
        public Parameter<double> BSIM3nsub { get; private set; }
        public Parameter<double> BSIM3npeak { get; private set; }
        public Parameter<double> BSIM3ngate { get; private set; }
        public Parameter<double> BSIM3gamma1 { get; private set; }
        public Parameter<double> BSIM3gamma2 { get; private set; }
        public Parameter<double> BSIM3vbx { get; private set; }
        public Parameter<double> BSIM3vbm { get; private set; }
        public Parameter<double> BSIM3xt { get; private set; }
        public Parameter<double> BSIM3k1 { get; private set; }
        public Parameter<double> BSIM3kt1 { get; private set; }
        public Parameter<double> BSIM3kt1l { get; private set; }
        public Parameter<double> BSIM3kt2 { get; private set; }
        public Parameter<double> BSIM3k2 { get; private set; }
        public Parameter<double> BSIM3k3 { get; private set; }
        public Parameter<double> BSIM3k3b { get; private set; }
        public Parameter<double> BSIM3w0 { get; private set; }
        public Parameter<double> BSIM3nlx { get; private set; }
        public Parameter<double> BSIM3dvt0 { get; private set; }
        public Parameter<double> BSIM3dvt1 { get; private set; }
        public Parameter<double> BSIM3dvt2 { get; private set; }
        public Parameter<double> BSIM3dvt0w { get; private set; }
        public Parameter<double> BSIM3dvt1w { get; private set; }
        public Parameter<double> BSIM3dvt2w { get; private set; }
        public Parameter<double> BSIM3drout { get; private set; }
        public Parameter<double> BSIM3dsub { get; private set; }
        public Parameter<double> BSIM3vth0 { get; private set; }
        public Parameter<double> BSIM3ua { get; private set; }
        public Parameter<double> BSIM3ua1 { get; private set; }
        public Parameter<double> BSIM3ub { get; private set; }
        public Parameter<double> BSIM3ub1 { get; private set; }
        public Parameter<double> BSIM3uc { get; private set; }
        public Parameter<double> BSIM3uc1 { get; private set; }
        public Parameter<double> BSIM3u0 { get; private set; }
        public Parameter<double> BSIM3ute { get; private set; }
        public Parameter<double> BSIM3voff { get; private set; }
        public Parameter<double> BSIM3rdsw { get; private set; }
        public Parameter<double> BSIM3prwg { get; private set; }
        public Parameter<double> BSIM3prwb { get; private set; }
        public Parameter<double> BSIM3prt { get; private set; }
        public Parameter<double> BSIM3eta0 { get; private set; }
        public Parameter<double> BSIM3etab { get; private set; }
        public Parameter<double> BSIM3pclm { get; private set; }
        public Parameter<double> BSIM3pdibl1 { get; private set; }
        public Parameter<double> BSIM3pdibl2 { get; private set; }
        public Parameter<double> BSIM3pdiblb { get; private set; }
        public Parameter<double> BSIM3pscbe1 { get; private set; }
        public Parameter<double> BSIM3pscbe2 { get; private set; }
        public Parameter<double> BSIM3pvag { get; private set; }
        public Parameter<double> BSIM3delta { get; private set; }
        public Parameter<double> BSIM3wr { get; private set; }
        public Parameter<double> BSIM3dwg { get; private set; }
        public Parameter<double> BSIM3dwb { get; private set; }
        public Parameter<double> BSIM3b0 { get; private set; }
        public Parameter<double> BSIM3b1 { get; private set; }
        public Parameter<double> BSIM3alpha0 { get; private set; }
        public Parameter<double> BSIM3alpha1 { get; private set; }
        public Parameter<double> BSIM3beta0 { get; private set; }
        public Parameter<double> BSIM3ijth { get; private set; }
        public Parameter<double> BSIM3vfb { get; private set; }

        /* CV model */
        public Parameter<double> BSIM3elm { get; private set; }
        public Parameter<double> BSIM3cgsl { get; private set; }
        public Parameter<double> BSIM3cgdl { get; private set; }
        public Parameter<double> BSIM3ckappa { get; private set; }
        public Parameter<double> BSIM3cf { get; private set; }
        public Parameter<double> BSIM3vfbcv { get; private set; }
        public Parameter<double> BSIM3clc { get; private set; }
        public Parameter<double> BSIM3cle { get; private set; }
        public Parameter<double> BSIM3dwc { get; private set; }
        public Parameter<double> BSIM3dlc { get; private set; }
        public Parameter<double> BSIM3noff { get; private set; }
        public Parameter<double> BSIM3voffcv { get; private set; }
        public Parameter<double> BSIM3acde { get; private set; }
        public Parameter<double> BSIM3moin { get; private set; }
        public Parameter<double> BSIM3tcj { get; private set; }
        public Parameter<double> BSIM3tcjsw { get; private set; }
        public Parameter<double> BSIM3tcjswg { get; private set; }
        public Parameter<double> BSIM3tpb { get; private set; }
        public Parameter<double> BSIM3tpbsw { get; private set; }
        public Parameter<double> BSIM3tpbswg { get; private set; }

        /* Length dependence */
        public Parameter<double> BSIM3lcdsc { get; private set; }
        public Parameter<double> BSIM3lcdscb { get; private set; }
        public Parameter<double> BSIM3lcdscd { get; private set; }
        public Parameter<double> BSIM3lcit { get; private set; }
        public Parameter<double> BSIM3lnfactor { get; private set; }
        public Parameter<double> BSIM3lxj { get; private set; }
        public Parameter<double> BSIM3lvsat { get; private set; }
        public Parameter<double> BSIM3lat { get; private set; }
        public Parameter<double> BSIM3la0 { get; private set; }
        public Parameter<double> BSIM3lags { get; private set; }
        public Parameter<double> BSIM3la1 { get; private set; }
        public Parameter<double> BSIM3la2 { get; private set; }
        public Parameter<double> BSIM3lketa { get; private set; }
        public Parameter<double> BSIM3lnsub { get; private set; }
        public Parameter<double> BSIM3lnpeak { get; private set; }
        public Parameter<double> BSIM3lngate { get; private set; }
        public Parameter<double> BSIM3lgamma1 { get; private set; }
        public Parameter<double> BSIM3lgamma2 { get; private set; }
        public Parameter<double> BSIM3lvbx { get; private set; }
        public Parameter<double> BSIM3lvbm { get; private set; }
        public Parameter<double> BSIM3lxt { get; private set; }
        public Parameter<double> BSIM3lk1 { get; private set; }
        public Parameter<double> BSIM3lkt1 { get; private set; }
        public Parameter<double> BSIM3lkt1l { get; private set; }
        public Parameter<double> BSIM3lkt2 { get; private set; }
        public Parameter<double> BSIM3lk2 { get; private set; }
        public Parameter<double> BSIM3lk3 { get; private set; }
        public Parameter<double> BSIM3lk3b { get; private set; }
        public Parameter<double> BSIM3lw0 { get; private set; }
        public Parameter<double> BSIM3lnlx { get; private set; }
        public Parameter<double> BSIM3ldvt0 { get; private set; }
        public Parameter<double> BSIM3ldvt1 { get; private set; }
        public Parameter<double> BSIM3ldvt2 { get; private set; }
        public Parameter<double> BSIM3ldvt0w { get; private set; }
        public Parameter<double> BSIM3ldvt1w { get; private set; }
        public Parameter<double> BSIM3ldvt2w { get; private set; }
        public Parameter<double> BSIM3ldrout { get; private set; }
        public Parameter<double> BSIM3ldsub { get; private set; }
        public Parameter<double> BSIM3lvth0 { get; private set; }
        public Parameter<double> BSIM3lua { get; private set; }
        public Parameter<double> BSIM3lua1 { get; private set; }
        public Parameter<double> BSIM3lub { get; private set; }
        public Parameter<double> BSIM3lub1 { get; private set; }
        public Parameter<double> BSIM3luc { get; private set; }
        public Parameter<double> BSIM3luc1 { get; private set; }
        public Parameter<double> BSIM3lu0 { get; private set; }
        public Parameter<double> BSIM3lute { get; private set; }
        public Parameter<double> BSIM3lvoff { get; private set; }
        public Parameter<double> BSIM3lrdsw { get; private set; }
        public Parameter<double> BSIM3lprwg { get; private set; }
        public Parameter<double> BSIM3lprwb { get; private set; }
        public Parameter<double> BSIM3lprt { get; private set; }
        public Parameter<double> BSIM3leta0 { get; private set; }
        public Parameter<double> BSIM3letab { get; private set; }
        public Parameter<double> BSIM3lpclm { get; private set; }
        public Parameter<double> BSIM3lpdibl1 { get; private set; }
        public Parameter<double> BSIM3lpdibl2 { get; private set; }
        public Parameter<double> BSIM3lpdiblb { get; private set; }
        public Parameter<double> BSIM3lpscbe1 { get; private set; }
        public Parameter<double> BSIM3lpscbe2 { get; private set; }
        public Parameter<double> BSIM3lpvag { get; private set; }
        public Parameter<double> BSIM3ldelta { get; private set; }
        public Parameter<double> BSIM3lwr { get; private set; }
        public Parameter<double> BSIM3ldwg { get; private set; }
        public Parameter<double> BSIM3ldwb { get; private set; }
        public Parameter<double> BSIM3lb0 { get; private set; }
        public Parameter<double> BSIM3lb1 { get; private set; }
        public Parameter<double> BSIM3lalpha0 { get; private set; }
        public Parameter<double> BSIM3lalpha1 { get; private set; }
        public Parameter<double> BSIM3lbeta0 { get; private set; }
        public Parameter<double> BSIM3lvfb { get; private set; }

        /* CV model */
        public Parameter<double> BSIM3lelm { get; private set; }
        public Parameter<double> BSIM3lcgsl { get; private set; }
        public Parameter<double> BSIM3lcgdl { get; private set; }
        public Parameter<double> BSIM3lckappa { get; private set; }
        public Parameter<double> BSIM3lcf { get; private set; }
        public Parameter<double> BSIM3lclc { get; private set; }
        public Parameter<double> BSIM3lcle { get; private set; }
        public Parameter<double> BSIM3lvfbcv { get; private set; }
        public Parameter<double> BSIM3lnoff { get; private set; }
        public Parameter<double> BSIM3lvoffcv { get; private set; }
        public Parameter<double> BSIM3lacde { get; private set; }
        public Parameter<double> BSIM3lmoin { get; private set; }

        /* Width dependence */
        public Parameter<double> BSIM3wcdsc { get; private set; }
        public Parameter<double> BSIM3wcdscb { get; private set; }
        public Parameter<double> BSIM3wcdscd { get; private set; }
        public Parameter<double> BSIM3wcit { get; private set; }
        public Parameter<double> BSIM3wnfactor { get; private set; }
        public Parameter<double> BSIM3wxj { get; private set; }
        public Parameter<double> BSIM3wvsat { get; private set; }
        public Parameter<double> BSIM3wat { get; private set; }
        public Parameter<double> BSIM3wa0 { get; private set; }
        public Parameter<double> BSIM3wags { get; private set; }
        public Parameter<double> BSIM3wa1 { get; private set; }
        public Parameter<double> BSIM3wa2 { get; private set; }
        public Parameter<double> BSIM3wketa { get; private set; }
        public Parameter<double> BSIM3wnsub { get; private set; }
        public Parameter<double> BSIM3wnpeak { get; private set; }
        public Parameter<double> BSIM3wngate { get; private set; }
        public Parameter<double> BSIM3wgamma1 { get; private set; }
        public Parameter<double> BSIM3wgamma2 { get; private set; }
        public Parameter<double> BSIM3wvbx { get; private set; }
        public Parameter<double> BSIM3wvbm { get; private set; }
        public Parameter<double> BSIM3wxt { get; private set; }
        public Parameter<double> BSIM3wk1 { get; private set; }
        public Parameter<double> BSIM3wkt1 { get; private set; }
        public Parameter<double> BSIM3wkt1l { get; private set; }
        public Parameter<double> BSIM3wkt2 { get; private set; }
        public Parameter<double> BSIM3wk2 { get; private set; }
        public Parameter<double> BSIM3wk3 { get; private set; }
        public Parameter<double> BSIM3wk3b { get; private set; }
        public Parameter<double> BSIM3ww0 { get; private set; }
        public Parameter<double> BSIM3wnlx { get; private set; }
        public Parameter<double> BSIM3wdvt0 { get; private set; }
        public Parameter<double> BSIM3wdvt1 { get; private set; }
        public Parameter<double> BSIM3wdvt2 { get; private set; }
        public Parameter<double> BSIM3wdvt0w { get; private set; }
        public Parameter<double> BSIM3wdvt1w { get; private set; }
        public Parameter<double> BSIM3wdvt2w { get; private set; }
        public Parameter<double> BSIM3wdrout { get; private set; }
        public Parameter<double> BSIM3wdsub { get; private set; }
        public Parameter<double> BSIM3wvth0 { get; private set; }
        public Parameter<double> BSIM3wua { get; private set; }
        public Parameter<double> BSIM3wua1 { get; private set; }
        public Parameter<double> BSIM3wub { get; private set; }
        public Parameter<double> BSIM3wub1 { get; private set; }
        public Parameter<double> BSIM3wuc { get; private set; }
        public Parameter<double> BSIM3wuc1 { get; private set; }
        public Parameter<double> BSIM3wu0 { get; private set; }
        public Parameter<double> BSIM3wute { get; private set; }
        public Parameter<double> BSIM3wvoff { get; private set; }
        public Parameter<double> BSIM3wrdsw { get; private set; }
        public Parameter<double> BSIM3wprwg { get; private set; }
        public Parameter<double> BSIM3wprwb { get; private set; }
        public Parameter<double> BSIM3wprt { get; private set; }
        public Parameter<double> BSIM3weta0 { get; private set; }
        public Parameter<double> BSIM3wetab { get; private set; }
        public Parameter<double> BSIM3wpclm { get; private set; }
        public Parameter<double> BSIM3wpdibl1 { get; private set; }
        public Parameter<double> BSIM3wpdibl2 { get; private set; }
        public Parameter<double> BSIM3wpdiblb { get; private set; }
        public Parameter<double> BSIM3wpscbe1 { get; private set; }
        public Parameter<double> BSIM3wpscbe2 { get; private set; }
        public Parameter<double> BSIM3wpvag { get; private set; }
        public Parameter<double> BSIM3wdelta { get; private set; }
        public Parameter<double> BSIM3wwr { get; private set; }
        public Parameter<double> BSIM3wdwg { get; private set; }
        public Parameter<double> BSIM3wdwb { get; private set; }
        public Parameter<double> BSIM3wb0 { get; private set; }
        public Parameter<double> BSIM3wb1 { get; private set; }
        public Parameter<double> BSIM3walpha0 { get; private set; }
        public Parameter<double> BSIM3walpha1 { get; private set; }
        public Parameter<double> BSIM3wbeta0 { get; private set; }
        public Parameter<double> BSIM3wvfb { get; private set; }


        /* CV model */
        public Parameter<double> BSIM3welm { get; private set; }
        public Parameter<double> BSIM3wcgsl { get; private set; }
        public Parameter<double> BSIM3wcgdl { get; private set; }
        public Parameter<double> BSIM3wckappa { get; private set; }
        public Parameter<double> BSIM3wcf { get; private set; }
        public Parameter<double> BSIM3wclc { get; private set; }
        public Parameter<double> BSIM3wcle { get; private set; }
        public Parameter<double> BSIM3wvfbcv { get; private set; }
        public Parameter<double> BSIM3wnoff { get; private set; }
        public Parameter<double> BSIM3wvoffcv { get; private set; }
        public Parameter<double> BSIM3wacde { get; private set; }
        public Parameter<double> BSIM3wmoin { get; private set; }


        /* Cross-term dependence */
        public Parameter<double> BSIM3pcdsc { get; private set; }
        public Parameter<double> BSIM3pcdscb { get; private set; }
        public Parameter<double> BSIM3pcdscd { get; private set; }
        public Parameter<double> BSIM3pcit { get; private set; }
        public Parameter<double> BSIM3pnfactor { get; private set; }
        public Parameter<double> BSIM3pxj { get; private set; }
        public Parameter<double> BSIM3pvsat { get; private set; }
        public Parameter<double> BSIM3pat { get; private set; }
        public Parameter<double> BSIM3pa0 { get; private set; }
        public Parameter<double> BSIM3pags { get; private set; }
        public Parameter<double> BSIM3pa1 { get; private set; }
        public Parameter<double> BSIM3pa2 { get; private set; }
        public Parameter<double> BSIM3pketa { get; private set; }
        public Parameter<double> BSIM3pnsub { get; private set; }
        public Parameter<double> BSIM3pnpeak { get; private set; }
        public Parameter<double> BSIM3pngate { get; private set; }
        public Parameter<double> BSIM3pgamma1 { get; private set; }
        public Parameter<double> BSIM3pgamma2 { get; private set; }
        public Parameter<double> BSIM3pvbx { get; private set; }
        public Parameter<double> BSIM3pvbm { get; private set; }
        public Parameter<double> BSIM3pxt { get; private set; }
        public Parameter<double> BSIM3pk1 { get; private set; }
        public Parameter<double> BSIM3pkt1 { get; private set; }
        public Parameter<double> BSIM3pkt1l { get; private set; }
        public Parameter<double> BSIM3pkt2 { get; private set; }
        public Parameter<double> BSIM3pk2 { get; private set; }
        public Parameter<double> BSIM3pk3 { get; private set; }
        public Parameter<double> BSIM3pk3b { get; private set; }
        public Parameter<double> BSIM3pw0 { get; private set; }
        public Parameter<double> BSIM3pnlx { get; private set; }
        public Parameter<double> BSIM3pdvt0 { get; private set; }
        public Parameter<double> BSIM3pdvt1 { get; private set; }
        public Parameter<double> BSIM3pdvt2 { get; private set; }
        public Parameter<double> BSIM3pdvt0w { get; private set; }
        public Parameter<double> BSIM3pdvt1w { get; private set; }
        public Parameter<double> BSIM3pdvt2w { get; private set; }
        public Parameter<double> BSIM3pdrout { get; private set; }
        public Parameter<double> BSIM3pdsub { get; private set; }
        public Parameter<double> BSIM3pvth0 { get; private set; }
        public Parameter<double> BSIM3pua { get; private set; }
        public Parameter<double> BSIM3pua1 { get; private set; }
        public Parameter<double> BSIM3pub { get; private set; }
        public Parameter<double> BSIM3pub1 { get; private set; }
        public Parameter<double> BSIM3puc { get; private set; }
        public Parameter<double> BSIM3puc1 { get; private set; }
        public Parameter<double> BSIM3pu0 { get; private set; }
        public Parameter<double> BSIM3pute { get; private set; }
        public Parameter<double> BSIM3pvoff { get; private set; }
        public Parameter<double> BSIM3prdsw { get; private set; }
        public Parameter<double> BSIM3pprwg { get; private set; }
        public Parameter<double> BSIM3pprwb { get; private set; }
        public Parameter<double> BSIM3pprt { get; private set; }
        public Parameter<double> BSIM3peta0 { get; private set; }
        public Parameter<double> BSIM3petab { get; private set; }
        public Parameter<double> BSIM3ppclm { get; private set; }
        public Parameter<double> BSIM3ppdibl1 { get; private set; }
        public Parameter<double> BSIM3ppdibl2 { get; private set; }
        public Parameter<double> BSIM3ppdiblb { get; private set; }
        public Parameter<double> BSIM3ppscbe1 { get; private set; }
        public Parameter<double> BSIM3ppscbe2 { get; private set; }
        public Parameter<double> BSIM3ppvag { get; private set; }
        public Parameter<double> BSIM3pdelta { get; private set; }
        public Parameter<double> BSIM3pwr { get; private set; }
        public Parameter<double> BSIM3pdwg { get; private set; }
        public Parameter<double> BSIM3pdwb { get; private set; }
        public Parameter<double> BSIM3pb0 { get; private set; }
        public Parameter<double> BSIM3pb1 { get; private set; }
        public Parameter<double> BSIM3palpha0 { get; private set; }
        public Parameter<double> BSIM3palpha1 { get; private set; }
        public Parameter<double> BSIM3pbeta0 { get; private set; }
        public Parameter<double> BSIM3pvfb { get; private set; }


        /* CV model */
        public Parameter<double> BSIM3pelm { get; private set; }
        public Parameter<double> BSIM3pcgsl { get; private set; }
        public Parameter<double> BSIM3pcgdl { get; private set; }
        public Parameter<double> BSIM3pckappa { get; private set; }
        public Parameter<double> BSIM3pcf { get; private set; }
        public Parameter<double> BSIM3pclc { get; private set; }
        public Parameter<double> BSIM3pcle { get; private set; }
        public Parameter<double> BSIM3pvfbcv { get; private set; }
        public Parameter<double> BSIM3pnoff { get; private set; }
        public Parameter<double> BSIM3pvoffcv { get; private set; }
        public Parameter<double> BSIM3pacde { get; private set; }
        public Parameter<double> BSIM3pmoin { get; private set; }
        public Parameter<double> BSIM3useFringe { get; private set; }
        public Parameter<double> BSIM3tnom { get; private set; }
        public Parameter<double> BSIM3cgso { get; private set; }
        public Parameter<double> BSIM3cgdo { get; private set; }
        public Parameter<double> BSIM3cgbo { get; private set; }
        public Parameter<double> BSIM3xpart { get; private set; }
        public Parameter<double> BSIM3sheetResistance { get; private set; }
        public Parameter<double> BSIM3jctSatCurDensity { get; private set; }
        public Parameter<double> BSIM3jctSidewallSatCurDensity { get; private set; }
        public Parameter<double> BSIM3bulkJctPotential { get; private set; }
        public Parameter<double> BSIM3bulkJctBotGradingCoeff { get; private set; }
        public Parameter<double> BSIM3sidewallJctPotential { get; private set; }
        public Parameter<double> BSIM3GatesidewallJctPotential { get; private set; }
        public Parameter<double> BSIM3bulkJctSideGradingCoeff { get; private set; }
        public Parameter<double> BSIM3unitAreaJctCap { get; private set; }
        public Parameter<double> BSIM3unitLengthSidewallJctCap { get; private set; }
        public Parameter<double> BSIM3bulkJctGateSideGradingCoeff { get; private set; }
        public Parameter<double> BSIM3unitLengthGateSidewallJctCap { get; private set; }
        public Parameter<double> BSIM3jctEmissionCoeff { get; private set; }
        public Parameter<double> BSIM3jctTempExponent { get; private set; }
        public Parameter<double> BSIM3oxideTrapDensityA { get; private set; }
        public Parameter<double> BSIM3oxideTrapDensityB { get; private set; }
        public Parameter<double> BSIM3oxideTrapDensityC { get; private set; }
        public Parameter<double> BSIM3em { get; private set; }
        public Parameter<double> BSIM3ef { get; private set; }
        public Parameter<double> BSIM3af { get; private set; }
        public Parameter<double> BSIM3kf { get; private set; }
        public Parameter<double> BSIM3lintnoi { get; private set; }
        public Parameter<double> BSIM3Lint { get; private set; }
        public Parameter<double> BSIM3Ll { get; private set; }
        public Parameter<double> BSIM3Llc { get; private set; }
        public Parameter<double> BSIM3Lln { get; private set; }
        public Parameter<double> BSIM3Lw { get; private set; }
        public Parameter<double> BSIM3Lwc { get; private set; }
        public Parameter<double> BSIM3Lwn { get; private set; }
        public Parameter<double> BSIM3Lwl { get; private set; }
        public Parameter<double> BSIM3Lwlc { get; private set; }
        public Parameter<double> BSIM3Lmin { get; private set; }
        public Parameter<double> BSIM3Lmax { get; private set; }
        public Parameter<double> BSIM3Wint { get; private set; }
        public Parameter<double> BSIM3Wl { get; private set; }
        public Parameter<double> BSIM3Wlc { get; private set; }
        public Parameter<double> BSIM3Wln { get; private set; }
        public Parameter<double> BSIM3Ww { get; private set; }
        public Parameter<double> BSIM3Wwc { get; private set; }
        public Parameter<double> BSIM3Wwn { get; private set; }
        public Parameter<double> BSIM3Wwl { get; private set; }
        public Parameter<double> BSIM3Wwlc { get; private set; }
        public Parameter<double> BSIM3Wmin { get; private set; }
        public Parameter<double> BSIM3Wmax { get; private set; }

        #endregion

        #region Calculated constants
        public double BSIM3cFringOut { get; private set; }
        public double BSIM3cFringMax { get; private set; }

        /* Pre-calculated constants */
        /* MCJ: move to size-dependent param. */
        public double BSIM3vtm { get; private set; }
        public double BSIM3cox { get; private set; }
        public double BSIM3cof1 { get; private set; }
        public double BSIM3cof2 { get; private set; }
        public double BSIM3cof3 { get; private set; }
        public double BSIM3cof4 { get; private set; }
        public double BSIM3vcrit { get; private set; }
        public double BSIM3factor1 { get; private set; }
        public double BSIM3PhiB { get; private set; }
        public double BSIM3PhiBSW { get; private set; }
        public double BSIM3PhiBSWG { get; private set; }
        public double BSIM3jctTempSatCurDensity { get; private set; }
        public double BSIM3jctSidewallTempSatCurDensity { get; private set; }
        public double BSIM3unitAreaTempJctCap { get; private set; }
        public double BSIM3unitLengthSidewallTempJctCap { get; private set; }
        public double BSIM3unitLengthGateSidewallTempJctCap { get; private set; }
        #endregion

        #region Constants
        public const double MAX_EXP = 5.834617425e14;
        public const double MIN_EXP = 1.713908431e-15;
        public const double EXP_THRESHOLD = 34.0;
        public const double SMOOTHFACTOR = 0.1;
        public const double EPSOX = 3.453133e-11;
        public const double EPSSI = 1.03594e-10;
        public const double PI = 3.141592654;
        public const double Charge_q = 1.60219e-19;
        public const double Meter2Micron = 1.0e6;
        public const double KboQ = 8.617087e-5;  /* Kb / q  where q = 1.60219e-19 */
        #endregion

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="name"></param>
        public BSIM3v3Model(string name)
            : base(name)
        {
            // Define parameters
            pTable.Add("capmod", new IP(IF.IOP, BSIM3capMod = new Parameter<int>(3), T.INTEGER, "Capacitance model selector"));
            pTable.Add("mobmod", new IP(IF.IOP, BSIM3mobMod = new Parameter<int>(1), T.INTEGER, "Mobility model selector"));
            pTable.Add("noimod", new IP(IF.IOP, BSIM3noiMod = new Parameter<int>(1), T.INTEGER, "Noise model selector"));
            pTable.Add("acnqsmod", new IP(IF.IOP, BSIM3acnqsMod = new Parameter<int>(1), T.INTEGER, "AC NQS model selector"));
            pTable.Add("paramchk", new IP(IF.IOP, BSIM3paramChk = new Parameter<int>(), T.INTEGER, "Model parameter checking selector"));
            pTable.Add("binunit", new IP(IF.IOP, BSIM3binUnit = new Parameter<int>(1), T.INTEGER, "Bin  unit  selector"));
            pTable.Add("version", new IP(IF.IOP, BSIM3version = new Parameter<string>("3.3.0"), T.STRING, " parameter for model version"));
            // Some versions are specified as doubles, so let's convert them if possible
            BSIM3version.InputFunc = (string value, Circuit ckt) =>
            {
                // Filter out all the numbers
                string version = "";
                for (int i = 0; i < value.Length; i++)
                    if (value[i] >= '0' && value[i] <= '9')
                        version += i > 0 ? "." + value[i].ToString() : value[i].ToString();
                BSIM3version.Value = version;
            };

            pTable.Add("tox", new IP(IF.IOP, BSIM3tox = new Parameter<double>(), T.REAL, "Gate oxide thickness in meters"));

            pTable.Add("toxm", new IP(IF.IOP, BSIM3toxm = new Parameter<double>(), T.REAL, "Gate oxide thickness used in extraction"));
            pTable.Add("cdsc", new IP(IF.IOP, BSIM3cdsc = new Parameter<double>(2.4e-4), T.REAL, "Drain/Source and channel coupling capacitance"));
            pTable.Add("cdscb", new IP(IF.IOP, BSIM3cdscb = new Parameter<double>(), T.REAL, "Body-bias dependence of cdsc"));
            pTable.Add("cdscd", new IP(IF.IOP, BSIM3cdscd = new Parameter<double>(), T.REAL, "Drain-bias dependence of cdsc"));
            pTable.Add("cit", new IP(IF.IOP, BSIM3cit = new Parameter<double>(), T.REAL, "Interface state capacitance"));
            pTable.Add("nfactor", new IP(IF.IOP, BSIM3nfactor = new Parameter<double>(1), T.REAL, "Subthreshold swing Coefficient"));
            pTable.Add("xj", new IP(IF.IOP, BSIM3xj = new Parameter<double>(0.15e-6), T.REAL, "Junction depth in meters"));
            pTable.Add("vsat", new IP(IF.IOP, BSIM3vsat = new Parameter<double>(8.0e4), T.REAL, "Saturation velocity at tnom"));
            pTable.Add("at", new IP(IF.IOP, BSIM3at = new Parameter<double>(3.3e4), T.REAL, "Temperature coefficient of vsat"));
            pTable.Add("a0", new IP(IF.IOP, BSIM3a0 = new Parameter<double>(1.0), T.REAL, "Non-uniform depletion width effect coefficient."));
            pTable.Add("ags", new IP(IF.IOP, BSIM3ags = new Parameter<double>(), T.REAL, "Gate bias  coefficient of Abulk."));
            pTable.Add("a1", new IP(IF.IOP, BSIM3a1 = new Parameter<double>(), T.REAL, "Non-saturation effect coefficient"));
            pTable.Add("a2", new IP(IF.IOP, BSIM3a2 = new Parameter<double>(1.0), T.REAL, "Non-saturation effect coefficient"));
            pTable.Add("keta", new IP(IF.IOP, BSIM3keta = new Parameter<double>(-0.047), T.REAL, "Body-bias coefficient of non-uniform depletion width effect."));
            pTable.Add("nsub", new IP(IF.IOP, BSIM3nsub = new Parameter<double>(6.0e16), T.REAL, "Substrate doping concentration"));
            pTable.Add("nch", new IP(IF.IOP, BSIM3npeak = new Parameter<double>(1.7e17), T.REAL, "Channel doping concentration"));
            BSIM3npeak.InputFunc = (double value, Circuit ckt) => { BSIM3npeak.Value = value > 1.0e20 ? value * 1e-6 : value; };
            pTable.Add("ngate", new IP(IF.IOP, BSIM3ngate = new Parameter<double>(), T.REAL, "Poly-gate doping concentration"));
            BSIM3ngate.InputFunc = (double value, Circuit ckt) => { BSIM3ngate.Value = value > 1.0e23 ? value * 1e-6 : value; };
            pTable.Add("gamma1", new IP(IF.IOP, BSIM3gamma1 = new Parameter<double>(), T.REAL, "Vth body coefficient"));
            pTable.Add("gamma2", new IP(IF.IOP, BSIM3gamma2 = new Parameter<double>(), T.REAL, "Vth body coefficient"));
            pTable.Add("vbx", new IP(IF.IOP, BSIM3vbx = new Parameter<double>(), T.REAL, "Vth transition body Voltage"));
            pTable.Add("vbm", new IP(IF.IOP, BSIM3vbm = new Parameter<double>(-3.0), T.REAL, "Maximum body voltage"));

            pTable.Add("xt", new IP(IF.IOP, BSIM3xt = new Parameter<double>(1.55e-7), T.REAL, "Doping depth"));
            pTable.Add("k1", new IP(IF.IOP, BSIM3k1 = new Parameter<double>(), T.REAL, "Bulk effect coefficient 1"));
            pTable.Add("kt1", new IP(IF.IOP, BSIM3kt1 = new Parameter<double>(-0.11), T.REAL, "Temperature coefficient of Vth"));
            pTable.Add("kt1l", new IP(IF.IOP, BSIM3kt1l = new Parameter<double>(), T.REAL, "Temperature coefficient of Vth"));
            pTable.Add("kt2", new IP(IF.IOP, BSIM3kt2 = new Parameter<double>(0.022), T.REAL, "Body-coefficient of kt1"));
            pTable.Add("k2", new IP(IF.IOP, BSIM3k2 = new Parameter<double>(), T.REAL, "Bulk effect coefficient 2"));
            pTable.Add("k3", new IP(IF.IOP, BSIM3k3 = new Parameter<double>(80.0), T.REAL, "Narrow width effect coefficient"));
            pTable.Add("k3b", new IP(IF.IOP, BSIM3k3b = new Parameter<double>(), T.REAL, "Body effect coefficient of k3"));
            pTable.Add("w0", new IP(IF.IOP, BSIM3w0 = new Parameter<double>(2.5e-6), T.REAL, "Narrow width effect parameter"));
            pTable.Add("nlx", new IP(IF.IOP, BSIM3nlx = new Parameter<double>(1.74e-7), T.REAL, "Lateral non-uniform doping effect"));
            pTable.Add("dvt0", new IP(IF.IOP, BSIM3dvt0 = new Parameter<double>(2.2), T.REAL, "Short channel effect coeff. 0"));
            pTable.Add("dvt1", new IP(IF.IOP, BSIM3dvt1 = new Parameter<double>(0.53), T.REAL, "Short channel effect coeff. 1"));
            pTable.Add("dvt2", new IP(IF.IOP, BSIM3dvt2 = new Parameter<double>(-0.032), T.REAL, "Short channel effect coeff. 2"));
            pTable.Add("dvt0w", new IP(IF.IOP, BSIM3dvt0w = new Parameter<double>(), T.REAL, "Narrow Width coeff. 0"));
            pTable.Add("dvt1w", new IP(IF.IOP, BSIM3dvt1w = new Parameter<double>(5.3e6), T.REAL, "Narrow Width effect coeff. 1"));
            pTable.Add("dvt2w", new IP(IF.IOP, BSIM3dvt2w = new Parameter<double>(-0.032), T.REAL, "Narrow Width effect coeff. 2"));
            pTable.Add("drout", new IP(IF.IOP, BSIM3drout = new Parameter<double>(0.56), T.REAL, "DIBL coefficient of output resistance"));
            pTable.Add("dsub", new IP(IF.IOP, BSIM3dsub = new Parameter<double>(), T.REAL, "DIBL coefficient in the subthreshold region"));
            pTable.Add("vth0", new IP(IF.IOP, BSIM3vth0 = new Parameter<double>(), T.REAL, "Threshold voltage"));
            pTable.Add("vtho", new IP(IF.IOP, BSIM3vth0, T.REAL, "Threshold voltage"));
            pTable.Add("ua", new IP(IF.IOP, BSIM3ua = new Parameter<double>(2.25e-9), T.REAL, "Linear gate dependence of mobility"));
            pTable.Add("ua1", new IP(IF.IOP, BSIM3ua1 = new Parameter<double>(4.31e-9), T.REAL, "Temperature coefficient of ua"));
            pTable.Add("ub", new IP(IF.IOP, BSIM3ub = new Parameter<double>(5.87e-19), T.REAL, "Quadratic gate dependence of mobility"));
            pTable.Add("ub1", new IP(IF.IOP, BSIM3ub1 = new Parameter<double>(-7.61e-18), T.REAL, "Temperature coefficient of ub"));
            pTable.Add("uc", new IP(IF.IOP, BSIM3uc = new Parameter<double>(), T.REAL, "Body-bias dependence of mobility"));
            pTable.Add("uc1", new IP(IF.IOP, BSIM3uc1 = new Parameter<double>(), T.REAL, "Temperature coefficient of uc"));
            pTable.Add("u0", new IP(IF.IOP, BSIM3u0 = new Parameter<double>(), T.REAL, "Low-field mobility at Tnom"));
            pTable.Add("ute", new IP(IF.IOP, BSIM3ute = new Parameter<double>(-1.5), T.REAL, "Temperature coefficient of mobility"));
            pTable.Add("voff", new IP(IF.IOP, BSIM3voff = new Parameter<double>(-0.08), T.REAL, "Threshold voltage offset"));
            pTable.Add("tnom", new IP(IF.IOP, BSIM3tnom = new Parameter<double>(300.15), T.REAL, "Parameter measurement temperature"));
            BSIM3tnom.InputFunc = (double value, Circuit ckt) => { BSIM3tnom.Value = value + Circuit.CONSTCtoK; }; // WARNING: This is not how they did it originally!
            BSIM3tnom.OutputFunc = (Circuit ckt) => { return BSIM3tnom.Value - Circuit.CONSTCtoK; };
            pTable.Add("cgso", new IP(IF.IOP, BSIM3cgso = new Parameter<double>(), T.REAL, "Gate-source overlap capacitance per width"));
            pTable.Add("cgdo", new IP(IF.IOP, BSIM3cgdo = new Parameter<double>(), T.REAL, "Gate-drain overlap capacitance per width"));
            pTable.Add("cgbo", new IP(IF.IOP, BSIM3cgbo = new Parameter<double>(), T.REAL, "Gate-bulk overlap capacitance per length"));
            pTable.Add("xpart", new IP(IF.IOP, BSIM3xpart = new Parameter<double>(), T.REAL, "Channel charge partitioning"));
            pTable.Add("elm", new IP(IF.IOP, BSIM3elm = new Parameter<double>(5.0), T.REAL, "Non-quasi-static Elmore Constant Parameter"));
            pTable.Add("delta", new IP(IF.IOP, BSIM3delta = new Parameter<double>(), T.REAL, "Effective Vds parameter"));
            pTable.Add("rsh", new IP(IF.IOP, BSIM3sheetResistance = new Parameter<double>(), T.REAL, "Source-drain sheet resistance"));
            pTable.Add("rdsw", new IP(IF.IOP, BSIM3rdsw = new Parameter<double>(), T.REAL, "Source-drain resistance per width"));

            pTable.Add("prwg", new IP(IF.IOP, BSIM3prwg = new Parameter<double>(), T.REAL, "Gate-bias effect on parasitic resistance "));
            pTable.Add("prwb", new IP(IF.IOP, BSIM3prwb = new Parameter<double>(), T.REAL, "Body-effect on parasitic resistance "));

            pTable.Add("prt", new IP(IF.IOP, BSIM3prt = new Parameter<double>(), T.REAL, "Temperature coefficient of parasitic resistance "));
            pTable.Add("eta0", new IP(IF.IOP, BSIM3eta0 = new Parameter<double>(0.08), T.REAL, "Subthreshold region DIBL coefficient"));
            pTable.Add("etab", new IP(IF.IOP, BSIM3etab = new Parameter<double>(-0.07), T.REAL, "Subthreshold region DIBL coefficient"));
            pTable.Add("pclm", new IP(IF.IOP, BSIM3pclm = new Parameter<double>(1.3), T.REAL, "Channel length modulation Coefficient"));
            pTable.Add("pdiblc1", new IP(IF.IOP, BSIM3pdibl1 = new Parameter<double>(0.39), T.REAL, "Drain-induced barrier lowering coefficient"));
            pTable.Add("pdiblc2", new IP(IF.IOP, BSIM3pdibl2 = new Parameter<double>(0.0086), T.REAL, "Drain-induced barrier lowering coefficient"));
            pTable.Add("pdiblcb", new IP(IF.IOP, BSIM3pdiblb = new Parameter<double>(), T.REAL, "Body-effect on drain-induced barrier lowering"));
            pTable.Add("pscbe1", new IP(IF.IOP, BSIM3pscbe1 = new Parameter<double>(4.24e8), T.REAL, "Substrate current body-effect coefficient"));
            pTable.Add("pscbe2", new IP(IF.IOP, BSIM3pscbe2 = new Parameter<double>(1.0e-5), T.REAL, "Substrate current body-effect coefficient"));
            pTable.Add("pvag", new IP(IF.IOP, BSIM3pvag = new Parameter<double>(), T.REAL, "Gate dependence of output resistance parameter"));
            pTable.Add("js", new IP(IF.IOP, BSIM3jctSatCurDensity = new Parameter<double>(), T.REAL, "Source/drain junction reverse saturation current density"));
            pTable.Add("jsw", new IP(IF.IOP, BSIM3jctSidewallSatCurDensity = new Parameter<double>(), T.REAL, "Sidewall junction reverse saturation current density"));
            pTable.Add("pb", new IP(IF.IOP, BSIM3bulkJctPotential = new Parameter<double>(), T.REAL, "Source/drain junction built-in potential"));
            pTable.Add("nj", new IP(IF.IOP, BSIM3jctEmissionCoeff = new Parameter<double>(), T.REAL, "Source/drain junction emission coefficient"));
            pTable.Add("xti", new IP(IF.IOP, BSIM3jctTempExponent = new Parameter<double>(), T.REAL, "Junction current temperature exponent"));
            pTable.Add("mj", new IP(IF.IOP, BSIM3bulkJctBotGradingCoeff = new Parameter<double>(), T.REAL, "Source/drain bottom junction capacitance grading coefficient"));
            pTable.Add("pbsw", new IP(IF.IOP, BSIM3sidewallJctPotential = new Parameter<double>(), T.REAL, "Source/drain sidewall junction capacitance built in potential"));
            pTable.Add("mjsw", new IP(IF.IOP, BSIM3bulkJctSideGradingCoeff = new Parameter<double>(), T.REAL, "Source/drain sidewall junction capacitance grading coefficient"));
            pTable.Add("pbswg", new IP(IF.IOP, BSIM3GatesidewallJctPotential = new Parameter<double>(), T.REAL, "Source/drain (gate side) sidewall junction capacitance built in potential"));
            pTable.Add("mjswg", new IP(IF.IOP, BSIM3bulkJctGateSideGradingCoeff = new Parameter<double>(), T.REAL, "Source/drain (gate side) sidewall junction capacitance grading coefficient"));
            pTable.Add("cj", new IP(IF.IOP, BSIM3unitAreaJctCap = new Parameter<double>(), T.REAL, "Source/drain bottom junction capacitance per unit area"));
            pTable.Add("vfbcv", new IP(IF.IOP, BSIM3vfbcv = new Parameter<double>(-1.0), T.REAL, "Flat Band Voltage parameter for capmod=0 only"));
            pTable.Add("vfb", new IP(IF.IOP, BSIM3vfb = new Parameter<double>(), T.REAL, "Flat Band Voltage"));
            pTable.Add("cjsw", new IP(IF.IOP, BSIM3unitLengthSidewallJctCap = new Parameter<double>(), T.REAL, "Source/drain sidewall junction capacitance per unit periphery"));
            pTable.Add("cjswg", new IP(IF.IOP, BSIM3unitLengthGateSidewallJctCap = new Parameter<double>(), T.REAL, "Source/drain (gate side) sidewall junction capacitance per unit width"));
            pTable.Add("tpb", new IP(IF.IOP, BSIM3tpb = new Parameter<double>(), T.REAL, "Temperature coefficient of pb"));
            pTable.Add("tcj", new IP(IF.IOP, BSIM3tcj = new Parameter<double>(), T.REAL, "Temperature coefficient of cj"));
            pTable.Add("tpbsw", new IP(IF.IOP, BSIM3tpbsw = new Parameter<double>(), T.REAL, "Temperature coefficient of pbsw"));
            pTable.Add("tcjsw", new IP(IF.IOP, BSIM3tcjsw = new Parameter<double>(), T.REAL, "Temperature coefficient of cjsw"));
            pTable.Add("tpbswg", new IP(IF.IOP, BSIM3tpbswg = new Parameter<double>(), T.REAL, "Temperature coefficient of pbswg"));
            pTable.Add("tcjswg", new IP(IF.IOP, BSIM3tcjswg = new Parameter<double>(), T.REAL, "Temperature coefficient of cjswg"));
            pTable.Add("acde", new IP(IF.IOP, BSIM3acde = new Parameter<double>(1.0), T.REAL, "Exponential coefficient for finite charge thickness"));
            pTable.Add("moin", new IP(IF.IOP, BSIM3moin = new Parameter<double>(15.0), T.REAL, "Coefficient for gate-bias dependent surface potential"));
            pTable.Add("noff", new IP(IF.IOP, BSIM3noff = new Parameter<double>(1.0), T.REAL, "C-V turn-on/off parameter"));
            pTable.Add("voffcv", new IP(IF.IOP, BSIM3voffcv = new Parameter<double>(), T.REAL, "C-V lateral-shift parameter"));
            pTable.Add("lintnoi", new IP(IF.IOP, BSIM3lintnoi = new Parameter<double>(), T.REAL, "lint offset for noise calculation"));
            pTable.Add("lint", new IP(IF.IOP, BSIM3Lint = new Parameter<double>(), T.REAL, "Length reduction parameter"));
            pTable.Add("ll", new IP(IF.IOP, BSIM3Ll = new Parameter<double>(), T.REAL, "Length reduction parameter"));
            pTable.Add("llc", new IP(IF.IOP, BSIM3Llc = new Parameter<double>(), T.REAL, "Length reduction parameter for CV"));
            pTable.Add("lln", new IP(IF.IOP, BSIM3Lln = new Parameter<double>(1.0), T.REAL, "Length reduction parameter"));
            pTable.Add("lw", new IP(IF.IOP, BSIM3Lw = new Parameter<double>(), T.REAL, "Length reduction parameter"));
            pTable.Add("lwc", new IP(IF.IOP, BSIM3Lwc = new Parameter<double>(), T.REAL, "Length reduction parameter for CV"));
            pTable.Add("lwn", new IP(IF.IOP, BSIM3Lwn = new Parameter<double>(1.0), T.REAL, "Length reduction parameter"));
            pTable.Add("lwl", new IP(IF.IOP, BSIM3Lwl = new Parameter<double>(), T.REAL, "Length reduction parameter"));
            pTable.Add("lwlc", new IP(IF.IOP, BSIM3Lwlc = new Parameter<double>(), T.REAL, "Length reduction parameter for CV"));
            pTable.Add("lmin", new IP(IF.IOP, BSIM3Lmin = new Parameter<double>(), T.REAL, "Minimum length for the model"));
            pTable.Add("lmax", new IP(IF.IOP, BSIM3Lmax = new Parameter<double>(1.0), T.REAL, "Maximum length for the model"));

            pTable.Add("wr", new IP(IF.IOP, BSIM3wr = new Parameter<double>(), T.REAL, "Width dependence of rds"));
            pTable.Add("wint", new IP(IF.IOP, BSIM3Wint = new Parameter<double>(), T.REAL, "Width reduction parameter"));
            pTable.Add("dwg", new IP(IF.IOP, BSIM3dwg = new Parameter<double>(), T.REAL, "Width reduction parameter"));
            pTable.Add("dwb", new IP(IF.IOP, BSIM3dwb = new Parameter<double>(), T.REAL, "Width reduction parameter"));

            pTable.Add("wl", new IP(IF.IOP, BSIM3Wl = new Parameter<double>(), T.REAL, "Width reduction parameter"));
            pTable.Add("wlc", new IP(IF.IOP, BSIM3Wlc = new Parameter<double>(), T.REAL, "Width reduction parameter for CV"));
            pTable.Add("wln", new IP(IF.IOP, BSIM3Wln = new Parameter<double>(1.0), T.REAL, "Width reduction parameter"));
            pTable.Add("ww", new IP(IF.IOP, BSIM3Ww = new Parameter<double>(), T.REAL, "Width reduction parameter"));
            pTable.Add("wwc", new IP(IF.IOP, BSIM3Wwc = new Parameter<double>(), T.REAL, "Width reduction parameter for CV"));
            pTable.Add("wwn", new IP(IF.IOP, BSIM3Wwn = new Parameter<double>(1.0), T.REAL, "Width reduction parameter"));
            pTable.Add("wwl", new IP(IF.IOP, BSIM3Wwl = new Parameter<double>(), T.REAL, "Width reduction parameter"));
            pTable.Add("wwlc", new IP(IF.IOP, BSIM3Wwlc = new Parameter<double>(), T.REAL, "Width reduction parameter for CV"));
            pTable.Add("wmin", new IP(IF.IOP, BSIM3Wmin = new Parameter<double>(), T.REAL, "Minimum width for the model"));
            pTable.Add("wmax", new IP(IF.IOP, BSIM3Wmax = new Parameter<double>(1.0), T.REAL, "Maximum width for the model"));

            pTable.Add("b0", new IP(IF.IOP, BSIM3b0 = new Parameter<double>(), T.REAL, "Abulk narrow width parameter"));
            pTable.Add("b1", new IP(IF.IOP, BSIM3b1 = new Parameter<double>(), T.REAL, "Abulk narrow width parameter"));

            pTable.Add("cgsl", new IP(IF.IOP, BSIM3cgsl = new Parameter<double>(), T.REAL, "New C-V model parameter"));
            pTable.Add("cgdl", new IP(IF.IOP, BSIM3cgdl = new Parameter<double>(), T.REAL, "New C-V model parameter"));
            pTable.Add("ckappa", new IP(IF.IOP, BSIM3ckappa = new Parameter<double>(0.6), T.REAL, "New C-V model parameter"));
            pTable.Add("cf", new IP(IF.IOP, BSIM3cf = new Parameter<double>(), T.REAL, "Fringe capacitance parameter"));
            pTable.Add("clc", new IP(IF.IOP, BSIM3clc = new Parameter<double>(0.1e-6), T.REAL, "Vdsat parameter for C-V model"));
            pTable.Add("cle", new IP(IF.IOP, BSIM3cle = new Parameter<double>(0.6), T.REAL, "Vdsat parameter for C-V model"));
            pTable.Add("dwc", new IP(IF.IOP, BSIM3dwc = new Parameter<double>(), T.REAL, "Delta W for C-V model"));
            pTable.Add("dlc", new IP(IF.IOP, BSIM3dlc = new Parameter<double>(), T.REAL, "Delta L for C-V model"));

            pTable.Add("alpha0", new IP(IF.IOP, BSIM3alpha0 = new Parameter<double>(), T.REAL, "substrate current model parameter"));
            pTable.Add("alpha1", new IP(IF.IOP, BSIM3alpha1 = new Parameter<double>(), T.REAL, "substrate current model parameter"));
            pTable.Add("beta0", new IP(IF.IOP, BSIM3beta0 = new Parameter<double>(), T.REAL, "substrate current model parameter"));
            pTable.Add("ijth", new IP(IF.IOP, BSIM3ijth = new Parameter<double>(0.1), T.REAL, "Diode limiting current"));

            pTable.Add("lcdsc", new IP(IF.IOP, BSIM3lcdsc = new Parameter<double>(), T.REAL, "Length dependence of cdsc"));
            pTable.Add("lcdscb", new IP(IF.IOP, BSIM3lcdscb = new Parameter<double>(), T.REAL, "Length dependence of cdscb"));
            pTable.Add("lcdscd", new IP(IF.IOP, BSIM3lcdscd = new Parameter<double>(), T.REAL, "Length dependence of cdscd"));
            pTable.Add("lcit", new IP(IF.IOP, BSIM3lcit = new Parameter<double>(), T.REAL, "Length dependence of cit"));
            pTable.Add("lnfactor", new IP(IF.IOP, BSIM3lnfactor = new Parameter<double>(), T.REAL, "Length dependence of nfactor"));
            pTable.Add("lxj", new IP(IF.IOP, BSIM3lxj = new Parameter<double>(), T.REAL, "Length dependence of xj"));
            pTable.Add("lvsat", new IP(IF.IOP, BSIM3lvsat = new Parameter<double>(), T.REAL, "Length dependence of vsat"));
            pTable.Add("lat", new IP(IF.IOP, BSIM3lat = new Parameter<double>(), T.REAL, "Length dependence of at"));
            pTable.Add("la0", new IP(IF.IOP, BSIM3la0 = new Parameter<double>(), T.REAL, "Length dependence of a0"));
            pTable.Add("lags", new IP(IF.IOP, BSIM3lags = new Parameter<double>(), T.REAL, "Length dependence of ags"));
            pTable.Add("la1", new IP(IF.IOP, BSIM3la1 = new Parameter<double>(), T.REAL, "Length dependence of a1"));
            pTable.Add("la2", new IP(IF.IOP, BSIM3la2 = new Parameter<double>(), T.REAL, "Length dependence of a2"));
            pTable.Add("lketa", new IP(IF.IOP, BSIM3lketa = new Parameter<double>(), T.REAL, "Length dependence of keta"));
            pTable.Add("lnsub", new IP(IF.IOP, BSIM3lnsub = new Parameter<double>(), T.REAL, "Length dependence of nsub"));
            pTable.Add("lnch", new IP(IF.IOP, BSIM3lnpeak = new Parameter<double>(), T.REAL, "Length dependence of nch"));
            BSIM3lnpeak.InputFunc = (double value, Circuit ckt) => { BSIM3lnpeak.Value = value > 1e20 ? value * 1e-6 : value; };
            pTable.Add("lngate", new IP(IF.IOP, BSIM3lngate = new Parameter<double>(), T.REAL, "Length dependence of ngate"));
            BSIM3lngate.InputFunc = (double value, Circuit ckt) => { BSIM3lngate.Value = value > 1e23 ? value * 1e-6 : value; };
            pTable.Add("lgamma1", new IP(IF.IOP, BSIM3lgamma1 = new Parameter<double>(), T.REAL, "Length dependence of gamma1"));
            pTable.Add("lgamma2", new IP(IF.IOP, BSIM3lgamma2 = new Parameter<double>(), T.REAL, "Length dependence of gamma2"));
            pTable.Add("lvbx", new IP(IF.IOP, BSIM3lvbx = new Parameter<double>(), T.REAL, "Length dependence of vbx"));
            pTable.Add("lvbm", new IP(IF.IOP, BSIM3lvbm = new Parameter<double>(), T.REAL, "Length dependence of vbm"));
            pTable.Add("lxt", new IP(IF.IOP, BSIM3lxt = new Parameter<double>(), T.REAL, "Length dependence of xt"));
            pTable.Add("lk1", new IP(IF.IOP, BSIM3lk1 = new Parameter<double>(), T.REAL, "Length dependence of k1"));
            pTable.Add("lkt1", new IP(IF.IOP, BSIM3lkt1 = new Parameter<double>(), T.REAL, "Length dependence of kt1"));
            pTable.Add("lkt1l", new IP(IF.IOP, BSIM3lkt1l = new Parameter<double>(), T.REAL, "Length dependence of kt1l"));
            pTable.Add("lkt2", new IP(IF.IOP, BSIM3lkt2 = new Parameter<double>(), T.REAL, "Length dependence of kt2"));
            pTable.Add("lk2", new IP(IF.IOP, BSIM3lk2 = new Parameter<double>(), T.REAL, "Length dependence of k2"));
            pTable.Add("lk3", new IP(IF.IOP, BSIM3lk3 = new Parameter<double>(), T.REAL, "Length dependence of k3"));
            pTable.Add("lk3b", new IP(IF.IOP, BSIM3lk3b = new Parameter<double>(), T.REAL, "Length dependence of k3b"));
            pTable.Add("lw0", new IP(IF.IOP, BSIM3lw0 = new Parameter<double>(), T.REAL, "Length dependence of w0"));
            pTable.Add("lnlx", new IP(IF.IOP, BSIM3lnlx = new Parameter<double>(), T.REAL, "Length dependence of nlx"));
            pTable.Add("ldvt0", new IP(IF.IOP, BSIM3ldvt0 = new Parameter<double>(), T.REAL, "Length dependence of dvt0"));
            pTable.Add("ldvt1", new IP(IF.IOP, BSIM3ldvt1 = new Parameter<double>(), T.REAL, "Length dependence of dvt1"));
            pTable.Add("ldvt2", new IP(IF.IOP, BSIM3ldvt2 = new Parameter<double>(), T.REAL, "Length dependence of dvt2"));
            pTable.Add("ldvt0w", new IP(IF.IOP, BSIM3ldvt0w = new Parameter<double>(), T.REAL, "Length dependence of dvt0w"));
            pTable.Add("ldvt1w", new IP(IF.IOP, BSIM3ldvt1w = new Parameter<double>(), T.REAL, "Length dependence of dvt1w"));
            pTable.Add("ldvt2w", new IP(IF.IOP, BSIM3ldvt2w = new Parameter<double>(), T.REAL, "Length dependence of dvt2w"));
            pTable.Add("ldrout", new IP(IF.IOP, BSIM3ldrout = new Parameter<double>(), T.REAL, "Length dependence of drout"));
            pTable.Add("ldsub", new IP(IF.IOP, BSIM3ldsub = new Parameter<double>(), T.REAL, "Length dependence of dsub"));
            pTable.Add("lvth0", new IP(IF.IOP, BSIM3lvth0 = new Parameter<double>(), T.REAL, "Length dependence of vto"));
            pTable.Add("lvtho", new IP(IF.IOP, BSIM3lvth0, T.REAL, "Length dependence of vto"));
            pTable.Add("lua", new IP(IF.IOP, BSIM3lua = new Parameter<double>(), T.REAL, "Length dependence of ua"));
            pTable.Add("lua1", new IP(IF.IOP, BSIM3lua1 = new Parameter<double>(), T.REAL, "Length dependence of ua1"));
            pTable.Add("lub", new IP(IF.IOP, BSIM3lub = new Parameter<double>(), T.REAL, "Length dependence of ub"));
            pTable.Add("lub1", new IP(IF.IOP, BSIM3lub1 = new Parameter<double>(), T.REAL, "Length dependence of ub1"));
            pTable.Add("luc", new IP(IF.IOP, BSIM3luc = new Parameter<double>(), T.REAL, "Length dependence of uc"));
            pTable.Add("luc1", new IP(IF.IOP, BSIM3luc1 = new Parameter<double>(), T.REAL, "Length dependence of uc1"));
            pTable.Add("lu0", new IP(IF.IOP, BSIM3lu0 = new Parameter<double>(), T.REAL, "Length dependence of u0"));
            pTable.Add("lute", new IP(IF.IOP, BSIM3lute = new Parameter<double>(), T.REAL, "Length dependence of ute"));
            pTable.Add("lvoff", new IP(IF.IOP, BSIM3lvoff = new Parameter<double>(), T.REAL, "Length dependence of voff"));
            pTable.Add("lelm", new IP(IF.IOP, BSIM3lelm = new Parameter<double>(), T.REAL, "Length dependence of elm"));
            pTable.Add("ldelta", new IP(IF.IOP, BSIM3ldelta = new Parameter<double>(), T.REAL, "Length dependence of delta"));
            pTable.Add("lrdsw", new IP(IF.IOP, BSIM3lrdsw = new Parameter<double>(), T.REAL, "Length dependence of rdsw "));

            pTable.Add("lprwg", new IP(IF.IOP, BSIM3lprwg = new Parameter<double>(), T.REAL, "Length dependence of prwg "));
            pTable.Add("lprwb", new IP(IF.IOP, BSIM3lprwb = new Parameter<double>(), T.REAL, "Length dependence of prwb "));

            pTable.Add("lprt", new IP(IF.IOP, BSIM3lprt = new Parameter<double>(), T.REAL, "Length dependence of prt "));
            pTable.Add("leta0", new IP(IF.IOP, BSIM3leta0 = new Parameter<double>(), T.REAL, "Length dependence of eta0"));
            pTable.Add("letab", new IP(IF.IOP, BSIM3letab = new Parameter<double>(), T.REAL, "Length dependence of etab"));
            pTable.Add("lpclm", new IP(IF.IOP, BSIM3lpclm = new Parameter<double>(), T.REAL, "Length dependence of pclm"));
            pTable.Add("lpdiblc1", new IP(IF.IOP, BSIM3lpdibl1 = new Parameter<double>(), T.REAL, "Length dependence of pdiblc1"));
            pTable.Add("lpdiblc2", new IP(IF.IOP, BSIM3lpdibl2 = new Parameter<double>(), T.REAL, "Length dependence of pdiblc2"));
            pTable.Add("lpdiblcb", new IP(IF.IOP, BSIM3lpdiblb = new Parameter<double>(), T.REAL, "Length dependence of pdiblcb"));
            pTable.Add("lpscbe1", new IP(IF.IOP, BSIM3lpscbe1 = new Parameter<double>(), T.REAL, "Length dependence of pscbe1"));
            pTable.Add("lpscbe2", new IP(IF.IOP, BSIM3lpscbe2 = new Parameter<double>(), T.REAL, "Length dependence of pscbe2"));
            pTable.Add("lpvag", new IP(IF.IOP, BSIM3lpvag = new Parameter<double>(), T.REAL, "Length dependence of pvag"));
            pTable.Add("lwr", new IP(IF.IOP, BSIM3lwr = new Parameter<double>(), T.REAL, "Length dependence of wr"));
            pTable.Add("ldwg", new IP(IF.IOP, BSIM3ldwg = new Parameter<double>(), T.REAL, "Length dependence of dwg"));
            pTable.Add("ldwb", new IP(IF.IOP, BSIM3ldwb = new Parameter<double>(), T.REAL, "Length dependence of dwb"));
            pTable.Add("lb0", new IP(IF.IOP, BSIM3lb0 = new Parameter<double>(), T.REAL, "Length dependence of b0"));
            pTable.Add("lb1", new IP(IF.IOP, BSIM3lb1 = new Parameter<double>(), T.REAL, "Length dependence of b1"));
            pTable.Add("lcgsl", new IP(IF.IOP, BSIM3lcgsl = new Parameter<double>(), T.REAL, "Length dependence of cgsl"));
            pTable.Add("lcgdl", new IP(IF.IOP, BSIM3lcgdl = new Parameter<double>(), T.REAL, "Length dependence of cgdl"));
            pTable.Add("lckappa", new IP(IF.IOP, BSIM3lckappa = new Parameter<double>(), T.REAL, "Length dependence of ckappa"));
            pTable.Add("lcf", new IP(IF.IOP, BSIM3lcf = new Parameter<double>(), T.REAL, "Length dependence of cf"));
            pTable.Add("lclc", new IP(IF.IOP, BSIM3lclc = new Parameter<double>(), T.REAL, "Length dependence of clc"));
            pTable.Add("lcle", new IP(IF.IOP, BSIM3lcle = new Parameter<double>(), T.REAL, "Length dependence of cle"));
            pTable.Add("lalpha0", new IP(IF.IOP, BSIM3lalpha0 = new Parameter<double>(), T.REAL, "Length dependence of alpha0"));
            pTable.Add("lalpha1", new IP(IF.IOP, BSIM3lalpha1 = new Parameter<double>(), T.REAL, "Length dependence of alpha1"));
            pTable.Add("lbeta0", new IP(IF.IOP, BSIM3lbeta0 = new Parameter<double>(), T.REAL, "Length dependence of beta0"));
            pTable.Add("lvfbcv", new IP(IF.IOP, BSIM3lvfbcv = new Parameter<double>(), T.REAL, "Length dependence of vfbcv"));
            pTable.Add("lvfb", new IP(IF.IOP, BSIM3lvfb = new Parameter<double>(), T.REAL, "Length dependence of vfb"));
            pTable.Add("lacde", new IP(IF.IOP, BSIM3lacde = new Parameter<double>(), T.REAL, "Length dependence of acde"));
            pTable.Add("lmoin", new IP(IF.IOP, BSIM3lmoin = new Parameter<double>(), T.REAL, "Length dependence of moin"));
            pTable.Add("lnoff", new IP(IF.IOP, BSIM3lnoff = new Parameter<double>(), T.REAL, "Length dependence of noff"));
            pTable.Add("lvoffcv", new IP(IF.IOP, BSIM3lvoffcv = new Parameter<double>(), T.REAL, "Length dependence of voffcv"));
            pTable.Add("wcdsc", new IP(IF.IOP, BSIM3wcdsc = new Parameter<double>(), T.REAL, "Width dependence of cdsc"));
            pTable.Add("wcdscb", new IP(IF.IOP, BSIM3wcdscb = new Parameter<double>(), T.REAL, "Width dependence of cdscb"));
            pTable.Add("wcdscd", new IP(IF.IOP, BSIM3wcdscd = new Parameter<double>(), T.REAL, "Width dependence of cdscd"));
            pTable.Add("wcit", new IP(IF.IOP, BSIM3wcit = new Parameter<double>(), T.REAL, "Width dependence of cit"));
            pTable.Add("wnfactor", new IP(IF.IOP, BSIM3wnfactor = new Parameter<double>(), T.REAL, "Width dependence of nfactor"));
            pTable.Add("wxj", new IP(IF.IOP, BSIM3wxj = new Parameter<double>(), T.REAL, "Width dependence of xj"));
            pTable.Add("wvsat", new IP(IF.IOP, BSIM3wvsat = new Parameter<double>(), T.REAL, "Width dependence of vsat"));
            pTable.Add("wat", new IP(IF.IOP, BSIM3wat = new Parameter<double>(), T.REAL, "Width dependence of at"));
            pTable.Add("wa0", new IP(IF.IOP, BSIM3wa0 = new Parameter<double>(), T.REAL, "Width dependence of a0"));
            pTable.Add("wags", new IP(IF.IOP, BSIM3wags = new Parameter<double>(), T.REAL, "Width dependence of ags"));
            pTable.Add("wa1", new IP(IF.IOP, BSIM3wa1 = new Parameter<double>(), T.REAL, "Width dependence of a1"));
            pTable.Add("wa2", new IP(IF.IOP, BSIM3wa2 = new Parameter<double>(), T.REAL, "Width dependence of a2"));
            pTable.Add("wketa", new IP(IF.IOP, BSIM3wketa = new Parameter<double>(), T.REAL, "Width dependence of keta"));
            pTable.Add("wnsub", new IP(IF.IOP, BSIM3wnsub = new Parameter<double>(), T.REAL, "Width dependence of nsub"));
            pTable.Add("wnch", new IP(IF.IOP, BSIM3wnpeak = new Parameter<double>(), T.REAL, "Width dependence of nch"));
            BSIM3wnpeak.InputFunc = (double value, Circuit ckt) => { BSIM3wnpeak.Value = value > 1e20 ? value * 1e-6 : value; };
            pTable.Add("wngate", new IP(IF.IOP, BSIM3wngate = new Parameter<double>(), T.REAL, "Width dependence of ngate"));
            BSIM3wngate.InputFunc = (double value, Circuit ckt) => { BSIM3wngate.Value = value > 1e23 ? value * 1e-6 : value; };
            pTable.Add("wgamma1", new IP(IF.IOP, BSIM3wgamma1 = new Parameter<double>(), T.REAL, "Width dependence of gamma1"));
            pTable.Add("wgamma2", new IP(IF.IOP, BSIM3wgamma2 = new Parameter<double>(), T.REAL, "Width dependence of gamma2"));
            pTable.Add("wvbx", new IP(IF.IOP, BSIM3wvbx = new Parameter<double>(), T.REAL, "Width dependence of vbx"));
            pTable.Add("wvbm", new IP(IF.IOP, BSIM3wvbm = new Parameter<double>(), T.REAL, "Width dependence of vbm"));
            pTable.Add("wxt", new IP(IF.IOP, BSIM3wxt = new Parameter<double>(), T.REAL, "Width dependence of xt"));
            pTable.Add("wk1", new IP(IF.IOP, BSIM3wk1 = new Parameter<double>(), T.REAL, "Width dependence of k1"));
            pTable.Add("wkt1", new IP(IF.IOP, BSIM3wkt1 = new Parameter<double>(), T.REAL, "Width dependence of kt1"));
            pTable.Add("wkt1l", new IP(IF.IOP, BSIM3wkt1l = new Parameter<double>(), T.REAL, "Width dependence of kt1l"));
            pTable.Add("wkt2", new IP(IF.IOP, BSIM3wkt2 = new Parameter<double>(), T.REAL, "Width dependence of kt2"));
            pTable.Add("wk2", new IP(IF.IOP, BSIM3wk2 = new Parameter<double>(), T.REAL, "Width dependence of k2"));
            pTable.Add("wk3", new IP(IF.IOP, BSIM3wk3 = new Parameter<double>(), T.REAL, "Width dependence of k3"));
            pTable.Add("wk3b", new IP(IF.IOP, BSIM3wk3b = new Parameter<double>(), T.REAL, "Width dependence of k3b"));
            pTable.Add("ww0", new IP(IF.IOP, BSIM3ww0 = new Parameter<double>(), T.REAL, "Width dependence of w0"));
            pTable.Add("wnlx", new IP(IF.IOP, BSIM3wnlx = new Parameter<double>(), T.REAL, "Width dependence of nlx"));
            pTable.Add("wdvt0", new IP(IF.IOP, BSIM3wdvt0 = new Parameter<double>(), T.REAL, "Width dependence of dvt0"));
            pTable.Add("wdvt1", new IP(IF.IOP, BSIM3wdvt1 = new Parameter<double>(), T.REAL, "Width dependence of dvt1"));
            pTable.Add("wdvt2", new IP(IF.IOP, BSIM3wdvt2 = new Parameter<double>(), T.REAL, "Width dependence of dvt2"));
            pTable.Add("wdvt0w", new IP(IF.IOP, BSIM3wdvt0w = new Parameter<double>(), T.REAL, "Width dependence of dvt0w"));
            pTable.Add("wdvt1w", new IP(IF.IOP, BSIM3wdvt1w = new Parameter<double>(), T.REAL, "Width dependence of dvt1w"));
            pTable.Add("wdvt2w", new IP(IF.IOP, BSIM3wdvt2w = new Parameter<double>(), T.REAL, "Width dependence of dvt2w"));
            pTable.Add("wdrout", new IP(IF.IOP, BSIM3wdrout = new Parameter<double>(), T.REAL, "Width dependence of drout"));
            pTable.Add("wdsub", new IP(IF.IOP, BSIM3wdsub = new Parameter<double>(), T.REAL, "Width dependence of dsub"));
            pTable.Add("wvth0", new IP(IF.IOP, BSIM3wvth0 = new Parameter<double>(), T.REAL, "Width dependence of vto"));
            pTable.Add("wvtho", new IP(IF.IOP, BSIM3wvth0, T.REAL, "Width dependence of vto"));
            pTable.Add("wua", new IP(IF.IOP, BSIM3wua = new Parameter<double>(), T.REAL, "Width dependence of ua"));
            pTable.Add("wua1", new IP(IF.IOP, BSIM3wua1 = new Parameter<double>(), T.REAL, "Width dependence of ua1"));
            pTable.Add("wub", new IP(IF.IOP, BSIM3wub = new Parameter<double>(), T.REAL, "Width dependence of ub"));
            pTable.Add("wub1", new IP(IF.IOP, BSIM3wub1 = new Parameter<double>(), T.REAL, "Width dependence of ub1"));
            pTable.Add("wuc", new IP(IF.IOP, BSIM3wuc = new Parameter<double>(), T.REAL, "Width dependence of uc"));
            pTable.Add("wuc1", new IP(IF.IOP, BSIM3wuc1 = new Parameter<double>(), T.REAL, "Width dependence of uc1"));
            pTable.Add("wu0", new IP(IF.IOP, BSIM3wu0 = new Parameter<double>(), T.REAL, "Width dependence of u0"));
            pTable.Add("wute", new IP(IF.IOP, BSIM3wute = new Parameter<double>(), T.REAL, "Width dependence of ute"));
            pTable.Add("wvoff", new IP(IF.IOP, BSIM3wvoff = new Parameter<double>(), T.REAL, "Width dependence of voff"));
            pTable.Add("welm", new IP(IF.IOP, BSIM3welm = new Parameter<double>(), T.REAL, "Width dependence of elm"));
            pTable.Add("wdelta", new IP(IF.IOP, BSIM3wdelta = new Parameter<double>(), T.REAL, "Width dependence of delta"));
            pTable.Add("wrdsw", new IP(IF.IOP, BSIM3wrdsw = new Parameter<double>(), T.REAL, "Width dependence of rdsw "));

            pTable.Add("wprwg", new IP(IF.IOP, BSIM3wprwg = new Parameter<double>(), T.REAL, "Width dependence of prwg "));
            pTable.Add("wprwb", new IP(IF.IOP, BSIM3wprwb = new Parameter<double>(), T.REAL, "Width dependence of prwb "));

            pTable.Add("wprt", new IP(IF.IOP, BSIM3wprt = new Parameter<double>(), T.REAL, "Width dependence of prt"));
            pTable.Add("weta0", new IP(IF.IOP, BSIM3weta0 = new Parameter<double>(), T.REAL, "Width dependence of eta0"));
            pTable.Add("wetab", new IP(IF.IOP, BSIM3wetab = new Parameter<double>(), T.REAL, "Width dependence of etab"));
            pTable.Add("wpclm", new IP(IF.IOP, BSIM3wpclm = new Parameter<double>(), T.REAL, "Width dependence of pclm"));
            pTable.Add("wpdiblc1", new IP(IF.IOP, BSIM3wpdibl1 = new Parameter<double>(), T.REAL, "Width dependence of pdiblc1"));
            pTable.Add("wpdiblc2", new IP(IF.IOP, BSIM3wpdibl2 = new Parameter<double>(), T.REAL, "Width dependence of pdiblc2"));
            pTable.Add("wpdiblcb", new IP(IF.IOP, BSIM3wpdiblb = new Parameter<double>(), T.REAL, "Width dependence of pdiblcb"));
            pTable.Add("wpscbe1", new IP(IF.IOP, BSIM3wpscbe1 = new Parameter<double>(), T.REAL, "Width dependence of pscbe1"));
            pTable.Add("wpscbe2", new IP(IF.IOP, BSIM3wpscbe2 = new Parameter<double>(), T.REAL, "Width dependence of pscbe2"));
            pTable.Add("wpvag", new IP(IF.IOP, BSIM3wpvag = new Parameter<double>(), T.REAL, "Width dependence of pvag"));
            pTable.Add("wwr", new IP(IF.IOP, BSIM3wwr = new Parameter<double>(), T.REAL, "Width dependence of wr"));
            pTable.Add("wdwg", new IP(IF.IOP, BSIM3wdwg = new Parameter<double>(), T.REAL, "Width dependence of dwg"));
            pTable.Add("wdwb", new IP(IF.IOP, BSIM3wdwb = new Parameter<double>(), T.REAL, "Width dependence of dwb"));
            pTable.Add("wb0", new IP(IF.IOP, BSIM3wb0 = new Parameter<double>(), T.REAL, "Width dependence of b0"));
            pTable.Add("wb1", new IP(IF.IOP, BSIM3wb1 = new Parameter<double>(), T.REAL, "Width dependence of b1"));
            pTable.Add("wcgsl", new IP(IF.IOP, BSIM3wcgsl = new Parameter<double>(), T.REAL, "Width dependence of cgsl"));
            pTable.Add("wcgdl", new IP(IF.IOP, BSIM3wcgdl = new Parameter<double>(), T.REAL, "Width dependence of cgdl"));
            pTable.Add("wckappa", new IP(IF.IOP, BSIM3wckappa = new Parameter<double>(), T.REAL, "Width dependence of ckappa"));
            pTable.Add("wcf", new IP(IF.IOP, BSIM3wcf = new Parameter<double>(), T.REAL, "Width dependence of cf"));
            pTable.Add("wclc", new IP(IF.IOP, BSIM3wclc = new Parameter<double>(), T.REAL, "Width dependence of clc"));
            pTable.Add("wcle", new IP(IF.IOP, BSIM3wcle = new Parameter<double>(), T.REAL, "Width dependence of cle"));
            pTable.Add("walpha0", new IP(IF.IOP, BSIM3walpha0 = new Parameter<double>(), T.REAL, "Width dependence of alpha0"));
            pTable.Add("walpha1", new IP(IF.IOP, BSIM3walpha1 = new Parameter<double>(), T.REAL, "Width dependence of alpha1"));
            pTable.Add("wbeta0", new IP(IF.IOP, BSIM3wbeta0 = new Parameter<double>(), T.REAL, "Width dependence of beta0"));
            pTable.Add("wvfbcv", new IP(IF.IOP, BSIM3wvfbcv = new Parameter<double>(), T.REAL, "Width dependence of vfbcv"));
            pTable.Add("wvfb", new IP(IF.IOP, BSIM3wvfb = new Parameter<double>(), T.REAL, "Width dependence of vfb"));
            pTable.Add("wacde", new IP(IF.IOP, BSIM3wacde = new Parameter<double>(), T.REAL, "Width dependence of acde"));
            pTable.Add("wmoin", new IP(IF.IOP, BSIM3wmoin = new Parameter<double>(), T.REAL, "Width dependence of moin"));
            pTable.Add("wnoff", new IP(IF.IOP, BSIM3wnoff = new Parameter<double>(), T.REAL, "Width dependence of noff"));
            pTable.Add("wvoffcv", new IP(IF.IOP, BSIM3wvoffcv = new Parameter<double>(), T.REAL, "Width dependence of voffcv"));

            pTable.Add("pcdsc", new IP(IF.IOP, BSIM3pcdsc = new Parameter<double>(), T.REAL, "Cross-term dependence of cdsc"));
            pTable.Add("pcdscb", new IP(IF.IOP, BSIM3pcdscb = new Parameter<double>(), T.REAL, "Cross-term dependence of cdscb"));
            pTable.Add("pcdscd", new IP(IF.IOP, BSIM3pcdscd = new Parameter<double>(), T.REAL, "Cross-term dependence of cdscd"));
            pTable.Add("pcit", new IP(IF.IOP, BSIM3pcit = new Parameter<double>(), T.REAL, "Cross-term dependence of cit"));
            pTable.Add("pnfactor", new IP(IF.IOP, BSIM3pnfactor = new Parameter<double>(), T.REAL, "Cross-term dependence of nfactor"));
            pTable.Add("pxj", new IP(IF.IOP, BSIM3pxj = new Parameter<double>(), T.REAL, "Cross-term dependence of xj"));
            pTable.Add("pvsat", new IP(IF.IOP, BSIM3pvsat = new Parameter<double>(), T.REAL, "Cross-term dependence of vsat"));
            pTable.Add("pat", new IP(IF.IOP, BSIM3pat = new Parameter<double>(), T.REAL, "Cross-term dependence of at"));
            pTable.Add("pa0", new IP(IF.IOP, BSIM3pa0 = new Parameter<double>(), T.REAL, "Cross-term dependence of a0"));
            pTable.Add("pags", new IP(IF.IOP, BSIM3pags = new Parameter<double>(), T.REAL, "Cross-term dependence of ags"));
            pTable.Add("pa1", new IP(IF.IOP, BSIM3pa1 = new Parameter<double>(), T.REAL, "Cross-term dependence of a1"));
            pTable.Add("pa2", new IP(IF.IOP, BSIM3pa2 = new Parameter<double>(), T.REAL, "Cross-term dependence of a2"));
            pTable.Add("pketa", new IP(IF.IOP, BSIM3pketa = new Parameter<double>(), T.REAL, "Cross-term dependence of keta"));
            pTable.Add("pnsub", new IP(IF.IOP, BSIM3pnsub = new Parameter<double>(), T.REAL, "Cross-term dependence of nsub"));
            pTable.Add("pnch", new IP(IF.IOP, BSIM3pnpeak = new Parameter<double>(), T.REAL, "Cross-term dependence of nch"));
            BSIM3pnpeak.InputFunc = (double value, Circuit ckt) => { BSIM3pnpeak.Value = value > 1e20 ? value * 1e-6 : value; };
            pTable.Add("pngate", new IP(IF.IOP, BSIM3pngate = new Parameter<double>(), T.REAL, "Cross-term dependence of ngate"));
            BSIM3pngate.InputFunc = (double value, Circuit ckt) => { BSIM3pngate.Value = value > 1e23 ? value * 1e-6 : value; };
            pTable.Add("pgamma1", new IP(IF.IOP, BSIM3pgamma1 = new Parameter<double>(), T.REAL, "Cross-term dependence of gamma1"));
            pTable.Add("pgamma2", new IP(IF.IOP, BSIM3pgamma2 = new Parameter<double>(), T.REAL, "Cross-term dependence of gamma2"));
            pTable.Add("pvbx", new IP(IF.IOP, BSIM3pvbx = new Parameter<double>(), T.REAL, "Cross-term dependence of vbx"));
            pTable.Add("pvbm", new IP(IF.IOP, BSIM3pvbm = new Parameter<double>(), T.REAL, "Cross-term dependence of vbm"));
            pTable.Add("pxt", new IP(IF.IOP, BSIM3pxt = new Parameter<double>(), T.REAL, "Cross-term dependence of xt"));
            pTable.Add("pk1", new IP(IF.IOP, BSIM3pk1 = new Parameter<double>(), T.REAL, "Cross-term dependence of k1"));
            pTable.Add("pkt1", new IP(IF.IOP, BSIM3pkt1 = new Parameter<double>(), T.REAL, "Cross-term dependence of kt1"));
            pTable.Add("pkt1l", new IP(IF.IOP, BSIM3pkt1l = new Parameter<double>(), T.REAL, "Cross-term dependence of kt1l"));
            pTable.Add("pkt2", new IP(IF.IOP, BSIM3pkt2 = new Parameter<double>(), T.REAL, "Cross-term dependence of kt2"));
            pTable.Add("pk2", new IP(IF.IOP, BSIM3pk2 = new Parameter<double>(), T.REAL, "Cross-term dependence of k2"));
            pTable.Add("pk3", new IP(IF.IOP, BSIM3pk3 = new Parameter<double>(), T.REAL, "Cross-term dependence of k3"));
            pTable.Add("pk3b", new IP(IF.IOP, BSIM3pk3b = new Parameter<double>(), T.REAL, "Cross-term dependence of k3b"));
            pTable.Add("pw0", new IP(IF.IOP, BSIM3pw0 = new Parameter<double>(), T.REAL, "Cross-term dependence of w0"));
            pTable.Add("pnlx", new IP(IF.IOP, BSIM3pnlx = new Parameter<double>(), T.REAL, "Cross-term dependence of nlx"));
            pTable.Add("pdvt0", new IP(IF.IOP, BSIM3pdvt0 = new Parameter<double>(), T.REAL, "Cross-term dependence of dvt0"));
            pTable.Add("pdvt1", new IP(IF.IOP, BSIM3pdvt1 = new Parameter<double>(), T.REAL, "Cross-term dependence of dvt1"));
            pTable.Add("pdvt2", new IP(IF.IOP, BSIM3pdvt2 = new Parameter<double>(), T.REAL, "Cross-term dependence of dvt2"));
            pTable.Add("pdvt0w", new IP(IF.IOP, BSIM3pdvt0w = new Parameter<double>(), T.REAL, "Cross-term dependence of dvt0w"));
            pTable.Add("pdvt1w", new IP(IF.IOP, BSIM3pdvt1w = new Parameter<double>(), T.REAL, "Cross-term dependence of dvt1w"));
            pTable.Add("pdvt2w", new IP(IF.IOP, BSIM3pdvt2w = new Parameter<double>(), T.REAL, "Cross-term dependence of dvt2w"));
            pTable.Add("pdrout", new IP(IF.IOP, BSIM3pdrout = new Parameter<double>(), T.REAL, "Cross-term dependence of drout"));
            pTable.Add("pdsub", new IP(IF.IOP, BSIM3pdsub = new Parameter<double>(), T.REAL, "Cross-term dependence of dsub"));
            pTable.Add("pvth0", new IP(IF.IOP, BSIM3pvth0 = new Parameter<double>(), T.REAL, "Cross-term dependence of vto"));
            pTable.Add("pvtho", new IP(IF.IOP, BSIM3pvth0, T.REAL, "Cross-term dependence of vto"));
            pTable.Add("pua", new IP(IF.IOP, BSIM3pua = new Parameter<double>(), T.REAL, "Cross-term dependence of ua"));
            pTable.Add("pua1", new IP(IF.IOP, BSIM3pua1 = new Parameter<double>(), T.REAL, "Cross-term dependence of ua1"));
            pTable.Add("pub", new IP(IF.IOP, BSIM3pub = new Parameter<double>(), T.REAL, "Cross-term dependence of ub"));
            pTable.Add("pub1", new IP(IF.IOP, BSIM3pub1 = new Parameter<double>(), T.REAL, "Cross-term dependence of ub1"));
            pTable.Add("puc", new IP(IF.IOP, BSIM3puc = new Parameter<double>(), T.REAL, "Cross-term dependence of uc"));
            pTable.Add("puc1", new IP(IF.IOP, BSIM3puc1 = new Parameter<double>(), T.REAL, "Cross-term dependence of uc1"));
            pTable.Add("pu0", new IP(IF.IOP, BSIM3pu0 = new Parameter<double>(), T.REAL, "Cross-term dependence of u0"));
            pTable.Add("pute", new IP(IF.IOP, BSIM3pute = new Parameter<double>(), T.REAL, "Cross-term dependence of ute"));
            pTable.Add("pvoff", new IP(IF.IOP, BSIM3pvoff = new Parameter<double>(), T.REAL, "Cross-term dependence of voff"));
            pTable.Add("pelm", new IP(IF.IOP, BSIM3pelm = new Parameter<double>(), T.REAL, "Cross-term dependence of elm"));
            pTable.Add("pdelta", new IP(IF.IOP, BSIM3pdelta = new Parameter<double>(), T.REAL, "Cross-term dependence of delta"));
            pTable.Add("prdsw", new IP(IF.IOP, BSIM3prdsw = new Parameter<double>(), T.REAL, "Cross-term dependence of rdsw "));

            pTable.Add("pprwg", new IP(IF.IOP, BSIM3pprwg = new Parameter<double>(), T.REAL, "Cross-term dependence of prwg "));
            pTable.Add("pprwb", new IP(IF.IOP, BSIM3pprwb = new Parameter<double>(), T.REAL, "Cross-term dependence of prwb "));

            pTable.Add("pprt", new IP(IF.IOP, BSIM3pprt = new Parameter<double>(), T.REAL, "Cross-term dependence of prt "));
            pTable.Add("peta0", new IP(IF.IOP, BSIM3peta0 = new Parameter<double>(), T.REAL, "Cross-term dependence of eta0"));
            pTable.Add("petab", new IP(IF.IOP, BSIM3petab = new Parameter<double>(), T.REAL, "Cross-term dependence of etab"));
            pTable.Add("ppclm", new IP(IF.IOP, BSIM3ppclm = new Parameter<double>(), T.REAL, "Cross-term dependence of pclm"));
            pTable.Add("ppdiblc1", new IP(IF.IOP, BSIM3ppdibl1 = new Parameter<double>(), T.REAL, "Cross-term dependence of pdiblc1"));
            pTable.Add("ppdiblc2", new IP(IF.IOP, BSIM3ppdibl2 = new Parameter<double>(), T.REAL, "Cross-term dependence of pdiblc2"));
            pTable.Add("ppdiblcb", new IP(IF.IOP, BSIM3ppdiblb = new Parameter<double>(), T.REAL, "Cross-term dependence of pdiblcb"));
            pTable.Add("ppscbe1", new IP(IF.IOP, BSIM3ppscbe1 = new Parameter<double>(), T.REAL, "Cross-term dependence of pscbe1"));
            pTable.Add("ppscbe2", new IP(IF.IOP, BSIM3ppscbe2 = new Parameter<double>(), T.REAL, "Cross-term dependence of pscbe2"));
            pTable.Add("ppvag", new IP(IF.IOP, BSIM3ppvag = new Parameter<double>(), T.REAL, "Cross-term dependence of pvag"));
            pTable.Add("pwr", new IP(IF.IOP, BSIM3pwr = new Parameter<double>(), T.REAL, "Cross-term dependence of wr"));
            pTable.Add("pdwg", new IP(IF.IOP, BSIM3pdwg = new Parameter<double>(), T.REAL, "Cross-term dependence of dwg"));
            pTable.Add("pdwb", new IP(IF.IOP, BSIM3pdwb = new Parameter<double>(), T.REAL, "Cross-term dependence of dwb"));
            pTable.Add("pb0", new IP(IF.IOP, BSIM3pb0 = new Parameter<double>(), T.REAL, "Cross-term dependence of b0"));
            pTable.Add("pb1", new IP(IF.IOP, BSIM3pb1 = new Parameter<double>(), T.REAL, "Cross-term dependence of b1"));
            pTable.Add("pcgsl", new IP(IF.IOP, BSIM3pcgsl = new Parameter<double>(), T.REAL, "Cross-term dependence of cgsl"));
            pTable.Add("pcgdl", new IP(IF.IOP, BSIM3pcgdl = new Parameter<double>(), T.REAL, "Cross-term dependence of cgdl"));
            pTable.Add("pckappa", new IP(IF.IOP, BSIM3pckappa = new Parameter<double>(), T.REAL, "Cross-term dependence of ckappa"));
            pTable.Add("pcf", new IP(IF.IOP, BSIM3pcf = new Parameter<double>(), T.REAL, "Cross-term dependence of cf"));
            pTable.Add("pclc", new IP(IF.IOP, BSIM3pclc = new Parameter<double>(), T.REAL, "Cross-term dependence of clc"));
            pTable.Add("pcle", new IP(IF.IOP, BSIM3pcle = new Parameter<double>(), T.REAL, "Cross-term dependence of cle"));
            pTable.Add("palpha0", new IP(IF.IOP, BSIM3palpha0 = new Parameter<double>(), T.REAL, "Cross-term dependence of alpha0"));
            pTable.Add("palpha1", new IP(IF.IOP, BSIM3palpha1 = new Parameter<double>(), T.REAL, "Cross-term dependence of alpha1"));
            pTable.Add("pbeta0", new IP(IF.IOP, BSIM3pbeta0 = new Parameter<double>(), T.REAL, "Cross-term dependence of beta0"));
            pTable.Add("pvfbcv", new IP(IF.IOP, BSIM3pvfbcv = new Parameter<double>(), T.REAL, "Cross-term dependence of vfbcv"));
            pTable.Add("pvfb", new IP(IF.IOP, BSIM3pvfb = new Parameter<double>(), T.REAL, "Cross-term dependence of vfb"));
            pTable.Add("pacde", new IP(IF.IOP, BSIM3pacde = new Parameter<double>(), T.REAL, "Cross-term dependence of acde"));
            pTable.Add("pmoin", new IP(IF.IOP, BSIM3pmoin = new Parameter<double>(), T.REAL, "Cross-term dependence of moin"));
            pTable.Add("pnoff", new IP(IF.IOP, BSIM3pnoff = new Parameter<double>(), T.REAL, "Cross-term dependence of noff"));
            pTable.Add("pvoffcv", new IP(IF.IOP, BSIM3pvoffcv = new Parameter<double>(), T.REAL, "Cross-term dependence of voffcv"));

            pTable.Add("noia", new IP(IF.IOP, BSIM3oxideTrapDensityA = new Parameter<double>(), T.REAL, "Flicker noise parameter"));
            pTable.Add("noib", new IP(IF.IOP, BSIM3oxideTrapDensityB = new Parameter<double>(), T.REAL, "Flicker noise parameter"));
            pTable.Add("noic", new IP(IF.IOP, BSIM3oxideTrapDensityC = new Parameter<double>(), T.REAL, "Flicker noise parameter"));
            pTable.Add("em", new IP(IF.IOP, BSIM3em = new Parameter<double>(), T.REAL, "Flicker noise parameter"));
            pTable.Add("ef", new IP(IF.IOP, BSIM3ef = new Parameter<double>(), T.REAL, "Flicker noise frequency exponent"));
            pTable.Add("af", new IP(IF.IOP, BSIM3af = new Parameter<double>(), T.REAL, "Flicker noise exponent"));
            pTable.Add("kf", new IP(IF.IOP, BSIM3kf = new Parameter<double>(), T.REAL, "Flicker noise coefficient"));

            BSIM3type = new Parameter<double>(1.0);
            pTable.Add("nmos", new IP(IF.IP, new InputParam((object value, Circuit ckt) => { BSIM3type.Value = 1.0; }), T.FLAG, "Flag to indicate NMOS"));
            pTable.Add("pmos", new IP(IF.IP, new InputParam((object value, Circuit ckt) => { BSIM3type.Value = -1.0; }), T.FLAG, "Flag to indicate PMOS"));
        }

        /// <summary>
        /// Setup the BSIM3 model
        /// </summary>
        /// <param name="ckt"></param>
        public override void Setup(Circuit ckt)
        {
            // Check version number
            if (BSIM3version != "3.3.0")
                throw new CircuitException(String.Format("Model {0} requires model version 3.3.0, version {1} specified.", Name, BSIM3version));

            /* Default value Processing for BSIM3 MOSFET Models */
            if (!BSIM3type.Given)
                BSIM3type.Value = 1;
            else if ((BSIM3acnqsMod != 0) && (BSIM3acnqsMod != 1))
            {
                BSIM3acnqsMod.Value = 0;
                CircuitWarning.Warning("Warning: acnqsMod has been set to its default value: 0.\n");
            }
            BSIM3cox = 3.453133e-11 / BSIM3tox;
            if (!BSIM3toxm.Given)
                BSIM3toxm.Value = BSIM3tox;
            if (!BSIM3xj.Given)
                BSIM3xj.Value = .15e-6;
            if (!BSIM3dsub.Given)
                BSIM3dsub.Value = BSIM3drout;
            if (!BSIM3vth0.Given)
                BSIM3vth0.Value = (BSIM3type == 1) ? 0.7 : -0.7;
            if (!BSIM3uc.Given)
                BSIM3uc.Value = (BSIM3mobMod == 3) ? -0.0465 : -0.0465e-9;
            if (!BSIM3uc1.Given)
                BSIM3uc1.Value = (BSIM3mobMod == 3) ? -0.056 : -0.056e-9;
            if (!BSIM3u0.Given)
                BSIM3u0.Value = (BSIM3type == 1) ? 0.067 : 0.025;
            if (!BSIM3pdibl1.Given)
                BSIM3pdibl1.Value = .39;    /* no unit  */

            /* Length dependence */

            /* Width dependence */

            /* Cross-term dependence */

            /* unit degree celcius */
            if (!BSIM3tnom.Given)
                BSIM3tnom.Value = ckt.Config.NominalTemperature;
            else
                BSIM3tnom.Value = BSIM3tnom + 273.15;
            if (!BSIM3Llc.Given)
                BSIM3Llc.Value = BSIM3Ll;
            if (!BSIM3Lwc.Given)
                BSIM3Lwc.Value = BSIM3Lw;
            if (!BSIM3Lwlc.Given)
                BSIM3Lwlc.Value = BSIM3Lwl;
            if (!BSIM3Wlc.Given)
                BSIM3Wlc.Value = BSIM3Wl;
            if (!BSIM3Wwc.Given)
                BSIM3Wwc.Value = BSIM3Ww;
            if (!BSIM3Wwlc.Given)
                BSIM3Wwlc.Value = BSIM3Wwl;
            if (!BSIM3dwc.Given)
                BSIM3dwc.Value = BSIM3Wint;
            if (!BSIM3dlc.Given)
                BSIM3dlc.Value = BSIM3Lint;
            if (!BSIM3cf.Given)
                BSIM3cf.Value = 2.0 * EPSOX / PI
                   * Math.Log(1.0 + 0.4e-6 / BSIM3tox);
            if (!BSIM3cgdo.Given)
            {
                if (BSIM3dlc.Given && (BSIM3dlc > 0.0))
                {
                    BSIM3cgdo.Value = BSIM3dlc * BSIM3cox
                         - BSIM3cgdl;
                }
                else
                    BSIM3cgdo.Value = 0.6 * BSIM3xj * BSIM3cox;
            }
            if (!BSIM3cgso.Given)
            {
                if (BSIM3dlc.Given && (BSIM3dlc > 0.0))
                {
                    BSIM3cgso.Value = BSIM3dlc * BSIM3cox
                         - BSIM3cgsl;
                }
                else
                    BSIM3cgso.Value = 0.6 * BSIM3xj * BSIM3cox;
            }

            if (!BSIM3cgbo.Given)
            {
                BSIM3cgbo.Value = 2.0 * BSIM3dwc * BSIM3cox;
            }
            if (!BSIM3unitLengthGateSidewallJctCap.Given)
                BSIM3unitLengthGateSidewallJctCap.Value = BSIM3unitLengthSidewallJctCap;
            if (!BSIM3GatesidewallJctPotential.Given)
                BSIM3GatesidewallJctPotential.Value = BSIM3sidewallJctPotential;
            if (!BSIM3bulkJctGateSideGradingCoeff.Given)
                BSIM3bulkJctGateSideGradingCoeff.Value = BSIM3bulkJctSideGradingCoeff;
            if (!BSIM3oxideTrapDensityA.Given)
            {
                if (BSIM3type == 1)
                    BSIM3oxideTrapDensityA.Value = 1e20;
                else
                    BSIM3oxideTrapDensityA.Value = 9.9e18;
            }
            if (!BSIM3oxideTrapDensityB.Given)
            {
                if (BSIM3type == 1)
                    BSIM3oxideTrapDensityB.Value = 5e4;
                else
                    BSIM3oxideTrapDensityB.Value = 2.4e3;
            }
            if (!BSIM3oxideTrapDensityC.Given)
            {
                if (BSIM3type == 1)
                    BSIM3oxideTrapDensityC.Value = -1.4e-12;
                else
                    BSIM3oxideTrapDensityC.Value = 1.4e-12;

            }

            base.Setup(ckt);
        }

        /// <summary>
        /// Model parameters used for the temperature-dependent calculations of instances
        /// </summary>
        public class BSIM3TempParameters
        {
            public double TRatio, Vtm0, ni;
        }

        /// <summary>
        /// Temperature-dependent calculations for the BSIM3 model
        /// </summary>
        /// <param name="ckt"></param>
        public override void Temperature(Circuit ckt)
        {
            double Eg, Eg0, T0, T1;
            double delTemp, Temp, Tnom;

            BSIM3TempParameters tp = new BSIM3TempParameters();

            Temp = ckt.Config.Temperature;
            if (this.BSIM3bulkJctPotential < 0.1)
            {
                this.BSIM3bulkJctPotential.Value = 0.1;
                CircuitWarning.Warning("Given pb is less than 0.1. Pb is set to 0.1.\n");
            }
            if (this.BSIM3sidewallJctPotential < 0.1)
            {
                this.BSIM3sidewallJctPotential.Value = 0.1;
                CircuitWarning.Warning("Given pbsw is less than 0.1. Pbsw is set to 0.1.\n");
            }
            if (this.BSIM3GatesidewallJctPotential < 0.1)
            {
                this.BSIM3GatesidewallJctPotential.Value = 0.1;
                CircuitWarning.Warning("Given pbswg is less than 0.1. Pbswg is set to 0.1.\n");
            }
            // this.pSizeDependParamKnot = NULL;
            // pLastKnot = NULL;

            Tnom = this.BSIM3tnom;
            tp.TRatio = Temp / Tnom;

            this.BSIM3vcrit = Circuit.CONSTvt0 * Math.Log(Circuit.CONSTvt0 / (Circuit.CONSTroot2 * 1.0e-14));
            this.BSIM3factor1 = Math.Sqrt(EPSSI / EPSOX * this.BSIM3tox);

            tp.Vtm0 = KboQ * Tnom;
            Eg0 = 1.16 - 7.02e-4 * Tnom * Tnom / (Tnom + 1108.0);
            tp.ni = 1.45e10 * (Tnom / 300.15) * Math.Sqrt(Tnom / 300.15) * Math.Exp(21.5565981 - Eg0 / (2.0 * tp.Vtm0));

            this.BSIM3vtm = KboQ * Temp;
            Eg = 1.16 - 7.02e-4 * Temp * Temp / (Temp + 1108.0);
            if (Temp != Tnom)
            {
                T0 = Eg0 / tp.Vtm0 - Eg / this.BSIM3vtm + this.BSIM3jctTempExponent * Math.Log(Temp / Tnom);
                T1 = Math.Exp(T0 / this.BSIM3jctEmissionCoeff);
                this.BSIM3jctTempSatCurDensity = this.BSIM3jctSatCurDensity * T1;
                this.BSIM3jctSidewallTempSatCurDensity = this.BSIM3jctSidewallSatCurDensity * T1;
            }
            else
            {
                this.BSIM3jctTempSatCurDensity = this.BSIM3jctSatCurDensity;
                this.BSIM3jctSidewallTempSatCurDensity = this.BSIM3jctSidewallSatCurDensity;
            }

            if (this.BSIM3jctTempSatCurDensity < 0.0)
                this.BSIM3jctTempSatCurDensity = 0.0;
            if (this.BSIM3jctSidewallTempSatCurDensity < 0.0)
                this.BSIM3jctSidewallTempSatCurDensity = 0.0;

            /* Temperature dependence of D/B and S/B diode capacitance begins */
            delTemp = ckt.Config.Temperature - this.BSIM3tnom;
            T0 = this.BSIM3tcj * delTemp;
            if (T0 >= -1.0)
            {
                this.BSIM3unitAreaTempJctCap = this.BSIM3unitAreaJctCap * (1.0 + T0);
            }
            else if (this.BSIM3unitAreaJctCap > 0.0)
            {
                this.BSIM3unitAreaTempJctCap = 0.0;
                CircuitWarning.Warning("Temperature effect has caused cj to be negative. Cj is clamped to zero.\n");
            }
            T0 = this.BSIM3tcjsw * delTemp;
            if (T0 >= -1.0)
            {
                this.BSIM3unitLengthSidewallTempJctCap = this.BSIM3unitLengthSidewallJctCap * (1.0 + T0);
            }
            else if (this.BSIM3unitLengthSidewallJctCap > 0.0)
            {
                this.BSIM3unitLengthSidewallTempJctCap = 0.0;
                CircuitWarning.Warning("Temperature effect has caused cjsw to be negative. Cjsw is clamped to zero.\n");
            }
            T0 = this.BSIM3tcjswg * delTemp;
            if (T0 >= -1.0)
            {
                this.BSIM3unitLengthGateSidewallTempJctCap = this.BSIM3unitLengthGateSidewallJctCap * (1.0 + T0);
            }
            else if (this.BSIM3unitLengthGateSidewallJctCap > 0.0)
            {
                this.BSIM3unitLengthGateSidewallTempJctCap = 0.0;
                CircuitWarning.Warning("Temperature effect has caused cjswg to be negative. Cjswg is clamped to zero.\n");
            }

            this.BSIM3PhiB = this.BSIM3bulkJctPotential - this.BSIM3tpb * delTemp;
            if (this.BSIM3PhiB < 0.01)
            {
                this.BSIM3PhiB = 0.01;
                CircuitWarning.Warning("Temperature effect has caused pb to be less than 0.01. Pb is clamped to 0.01.\n");
            }
            this.BSIM3PhiBSW = this.BSIM3sidewallJctPotential - this.BSIM3tpbsw * delTemp;
            if (this.BSIM3PhiBSW <= 0.01)
            {
                this.BSIM3PhiBSW = 0.01;
                CircuitWarning.Warning("Temperature effect has caused pbsw to be less than 0.01. Pbsw is clamped to 0.01.\n");
            }
            this.BSIM3PhiBSWG = this.BSIM3GatesidewallJctPotential - this.BSIM3tpbswg * delTemp;
            if (this.BSIM3PhiBSWG <= 0.01)
            {
                this.BSIM3PhiBSWG = 0.01;
                CircuitWarning.Warning("Temperature effect has caused pbswg to be less than 0.01. Pbswg is clamped to 0.01.\n");
            }

            /* End of junction capacitance */
            foreach (var inst in Instances)
                inst.Temperature(ckt, tp);
        }

        /// <summary>
        /// Model parameters used for loading instances
        /// </summary>
        public struct BSIM3LoadParameters
        {
            public double ScalingFactor;
            public bool ChargeComputationNeeded;
        }

        /// <summary>
        /// Loading for the BSIM3 model
        /// </summary>
        /// <param name="ckt"></param>
        public override void Load(Circuit ckt)
        {
            // Calculate model parameters
            BSIM3LoadParameters lp = new BSIM3LoadParameters();
            lp.ScalingFactor = 1.0e-9;
            lp.ChargeComputationNeeded =
                (((ckt.Mode & (Circuit.Modes.Ac | Circuit.Modes.Tran | Circuit.Modes.InitSmSig)) != 0) ||
                 (((ckt.Mode & Circuit.Modes.TranOp) != 0) && ((ckt.Mode & Circuit.Modes.Uic) != 0)))
                 ? true : false;

            foreach (var inst in Instances)
                inst.Load(ckt, lp);
        }
    }
}
